/[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 1200 by iliev, Thu May 24 14:04:18 2007 UTC revision 1644 by persson, Sat Jan 19 16:55:03 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  #if HAVE_SQLITE3  #include "../common/global_private.h"
24    
25  #include <iostream>  #include <iostream>
26  #include <sstream>  #include <sstream>
# Line 33  Line 33 
33    
34  namespace LinuxSampler {  namespace LinuxSampler {
35    
36      InstrumentsDb* InstrumentsDb::pInstrumentsDb = new InstrumentsDb;      InstrumentsDb InstrumentsDb::instance;
37    
38      void InstrumentsDb::CreateInstrumentsDb(String File) {      void InstrumentsDb::CreateInstrumentsDb(String File) {
39          struct stat statBuf;          struct stat statBuf;
# Line 58  namespace LinuxSampler { Line 58  namespace LinuxSampler {
58                    
59          GetInstrumentsDb()->ExecSql(sql);          GetInstrumentsDb()->ExecSql(sql);
60    
61          sql = "INSERT INTO instr_dirs (dir_id, parent_dir_id, dir_name) VALUES (0, 0, '/');";          sql = "INSERT INTO instr_dirs (dir_id, parent_dir_id, dir_name) VALUES (0, -2, '/');";
62          GetInstrumentsDb()->ExecSql(sql);          GetInstrumentsDb()->ExecSql(sql);
63    
64          sql =          sql =
# 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 127  namespace LinuxSampler { Line 120  namespace LinuxSampler {
120      sqlite3* InstrumentsDb::GetDb() {      sqlite3* InstrumentsDb::GetDb() {
121          if ( db != NULL) return db;          if ( db != NULL) return db;
122    
123          if (DbFile.empty()) DbFile = "/var/lib/linuxsampler/instruments.db";          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 136  namespace LinuxSampler { Line 133  namespace LinuxSampler {
133          }          }
134          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);
135          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."); }
136    
137            // TODO: remove this in the next version
138            try {
139                int i = ExecSqlInt("SELECT parent_dir_id FROM instr_dirs WHERE dir_id=0");
140                // The parent ID of the root directory should be -2 now.
141                if(i != -2) ExecSql("UPDATE instr_dirs SET parent_dir_id=-2 WHERE dir_id=0");
142            } catch(Exception e) { }
143            ////////////////////////////////////////
144                    
145          return db;          return db;
146      }      }
# Line 149  namespace LinuxSampler { Line 154  namespace LinuxSampler {
154                    
155          int count = ExecSqlInt(sql.str());          int count = ExecSqlInt(sql.str());
156    
         // While the root dir has ID 0 and parent ID 0, the directory  
         // count for the root dir will be incorrect, so we should fix it.  
         if (count != -1 && DirId == 0) count--;  
157          return count;          return count;
158      }      }
159    
# Line 173  namespace LinuxSampler { Line 175  namespace LinuxSampler {
175              throw e;              throw e;
176          }          }
177          EndTransaction();          EndTransaction();
178          if (i == -1) throw Exception("Unkown DB directory: " + Dir);          if (i == -1) throw Exception("Unkown DB directory: " + toEscapedPath(Dir));
179                    
180          return i;          return i;
181      }      }
# Line 192  namespace LinuxSampler { Line 194  namespace LinuxSampler {
194          BeginTransaction();          BeginTransaction();
195          try {          try {
196              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
197              if(dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if(dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
198    
199              StringListPtr pDirs;              StringListPtr pDirs;
200              if (Recursive) {              if (Recursive) {
# Line 215  namespace LinuxSampler { Line 217  namespace LinuxSampler {
217          std::stringstream sql;          std::stringstream sql;
218          sql << "SELECT dir_name FROM instr_dirs ";          sql << "SELECT dir_name FROM instr_dirs ";
219          sql << "WHERE parent_dir_id=" << DirId << " AND dir_id!=0";          sql << "WHERE parent_dir_id=" << DirId << " AND dir_id!=0";
220          return ExecSqlStringList(sql.str());          StringListPtr dirs = ExecSqlStringList(sql.str());
221    
222            for (int i = 0; i < dirs->size(); i++) {
223                for (int j = 0; j < dirs->at(i).length(); j++) {
224                    if (dirs->at(i).at(j) == '/') dirs->at(i).at(j) = '\0';
225                }
226            }
227    
228            return dirs;
229      }      }
230    
231      int InstrumentsDb::GetDirectoryId(String Dir) {      int InstrumentsDb::GetDirectoryId(String Dir) {
# Line 244  namespace LinuxSampler { Line 254  namespace LinuxSampler {
254    
255      int InstrumentsDb::GetDirectoryId(int ParentDirId, String DirName) {      int InstrumentsDb::GetDirectoryId(int ParentDirId, String DirName) {
256          dmsg(2,("InstrumentsDb: GetDirectoryId(ParentDirId=%d, DirName=%s)\n", ParentDirId, DirName.c_str()));          dmsg(2,("InstrumentsDb: GetDirectoryId(ParentDirId=%d, DirName=%s)\n", ParentDirId, DirName.c_str()));
257            DirName = toDbName(DirName);
258          std::stringstream sql;          std::stringstream sql;
259          sql << "SELECT dir_id FROM instr_dirs WHERE parent_dir_id=";          sql << "SELECT dir_id FROM instr_dirs WHERE parent_dir_id=";
260          sql << ParentDirId << " AND dir_name=?";          sql << ParentDirId << " AND dir_name=?";
# Line 296  namespace LinuxSampler { Line 307  namespace LinuxSampler {
307    
308              String dirName = GetFileName(Dir);              String dirName = GetFileName(Dir);
309              if(ParentDir.empty() || dirName.empty()) {              if(ParentDir.empty() || dirName.empty()) {
310                  throw Exception("Failed to add DB directory: " + Dir);                  throw Exception("Failed to add DB directory: " + toEscapedPath(Dir));
311              }              }
312    
313              int id = GetDirectoryId(ParentDir);              int id = GetDirectoryId(ParentDir);
314              if (id == -1) throw Exception("DB directory doesn't exist: " + ParentDir);              if (id == -1) throw Exception("DB directory doesn't exist: " + toEscapedPath(ParentDir));
315              int id2 = GetDirectoryId(id, dirName);              int id2 = GetDirectoryId(id, dirName);
316              if (id2 != -1) throw Exception("DB directory already exist: " + Dir);              if (id2 != -1) throw Exception("DB directory already exist: " + toEscapedPath(Dir));
317              id2 = GetInstrumentId(id, dirName);              id2 = GetInstrumentId(id, dirName);
318              if (id2 != -1) throw Exception("Instrument with that name exist: " + Dir);              if (id2 != -1) throw Exception("Instrument with that name exist: " + toEscapedPath(Dir));
319    
320              std::stringstream sql;              std::stringstream sql;
321              sql << "INSERT INTO instr_dirs (parent_dir_id, dir_name) VALUES (";              sql << "INSERT INTO instr_dirs (parent_dir_id, dir_name) VALUES (";
322              sql << id << ", ?)";              sql << id << ", ?)";
323    
324              ExecSql(sql.str(), dirName);              ExecSql(sql.str(), toDbName(dirName));
325          } catch (Exception e) {          } catch (Exception e) {
326              EndTransaction();              EndTransaction();
327              throw e;              throw e;
# Line 329  namespace LinuxSampler { Line 340  namespace LinuxSampler {
340          BeginTransaction();          BeginTransaction();
341          try {          try {
342              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
343              if (dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
344              if (dirId == 0) throw Exception("Cannot delete the root directory: " + Dir);              if (dirId == 0) throw Exception("Cannot delete the root directory: " + Dir);
345              if(ParentDir.empty()) throw Exception("Unknown parent directory");              if(ParentDir.empty()) throw Exception("Unknown parent directory");
346              if (Force) RemoveDirectoryContent(dirId);              if (Force) RemoveDirectoryContent(dirId);
# Line 416  namespace LinuxSampler { Line 427  namespace LinuxSampler {
427    
428          try {          try {
429              int id = GetDirectoryId(Dir);              int id = GetDirectoryId(Dir);
430              if(id == -1) throw Exception("Unknown DB directory: " + Dir);              if(id == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
431    
432              sqlite3_stmt *pStmt = NULL;              sqlite3_stmt *pStmt = NULL;
433              std::stringstream sql;              std::stringstream sql;
# Line 439  namespace LinuxSampler { Line 450  namespace LinuxSampler {
450                  if (res != SQLITE_DONE) {                  if (res != SQLITE_DONE) {
451                      throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));                      throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
452                  } else {                  } else {
453                      throw Exception("Unknown DB directory: " + Dir);                      throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
454                  }                  }
455              }              }
456                            
# Line 456  namespace LinuxSampler { Line 467  namespace LinuxSampler {
467      void InstrumentsDb::RenameDirectory(String Dir, String Name) {      void InstrumentsDb::RenameDirectory(String Dir, String Name) {
468          dmsg(2,("InstrumentsDb: RenameDirectory(Dir=%s,Name=%s)\n", Dir.c_str(), Name.c_str()));          dmsg(2,("InstrumentsDb: RenameDirectory(Dir=%s,Name=%s)\n", Dir.c_str(), Name.c_str()));
469          CheckFileName(Name);          CheckFileName(Name);
470            String dbName = toDbName(Name);
471    
472          BeginTransaction();          BeginTransaction();
473          try {          try {
474              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
475              if (dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedText(Dir));
476    
477              std::stringstream sql;              std::stringstream sql;
478              sql << "SELECT parent_dir_id FROM instr_dirs WHERE dir_id=" <<  dirId;              sql << "SELECT parent_dir_id FROM instr_dirs WHERE dir_id=" <<  dirId;
479    
480              int parent = ExecSqlInt(sql.str());              int parent = ExecSqlInt(sql.str());
481              if (parent == -1) throw Exception("Unknown parent directory: " + Dir);              if (parent == -1) throw Exception("Unknown parent directory: " + toEscapedPath(Dir));
482              if (GetDirectoryId(parent, Name) != -1) {  
483                  throw Exception("Cannot rename. Directory with that name already exists: " + Name);              if (GetDirectoryId(parent, dbName) != -1) {
484                    String s = toEscapedPath(Name);
485                    throw Exception("Cannot rename. Directory with that name already exists: " + s);
486              }              }
487    
488              if (GetInstrumentId(parent, Name) != -1) {              if (GetInstrumentId(parent, dbName) != -1) {
489                  throw Exception("Cannot rename. Instrument with that name exist: " + Dir);                  throw Exception("Cannot rename. Instrument with that name exist: " + toEscapedPath(Dir));
490              }              }
491    
492              sql.str("");              sql.str("");
493              sql << "UPDATE instr_dirs SET dir_name=? WHERE dir_id=" << dirId;              sql << "UPDATE instr_dirs SET dir_name=? WHERE dir_id=" << dirId;
494              ExecSql(sql.str(), Name);              ExecSql(sql.str(), dbName);
495          } catch (Exception e) {          } catch (Exception e) {
496              EndTransaction();              EndTransaction();
497              throw e;              throw e;
498          }          }
499    
500          EndTransaction();          EndTransaction();
501          FireDirectoryNameChanged(Dir, Name);          FireDirectoryNameChanged(Dir, toAbstractName(Name));
502      }      }
503    
504      void InstrumentsDb::MoveDirectory(String Dir, String Dst) {      void InstrumentsDb::MoveDirectory(String Dir, String Dst) {
# Line 497  namespace LinuxSampler { Line 511  namespace LinuxSampler {
511          BeginTransaction();          BeginTransaction();
512          try {          try {
513              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
514              if (dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
515              int dstId = GetDirectoryId(Dst);              int dstId = GetDirectoryId(Dst);
516              if (dstId == -1) throw Exception("Unknown DB directory: " + Dst);              if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
517              if (dirId == dstId) {              if (dirId == dstId) {
518                  throw Exception("Cannot move directory to itself");                  throw Exception("Cannot move directory to itself");
519              }              }
# Line 515  namespace LinuxSampler { Line 529  namespace LinuxSampler {
529              String dirName = GetFileName(Dir);              String dirName = GetFileName(Dir);
530    
531              int id2 = GetDirectoryId(dstId, dirName);              int id2 = GetDirectoryId(dstId, dirName);
532              if (id2 != -1) throw Exception("DB directory already exist: " + dirName);              if (id2 != -1) throw Exception("DB directory already exist: " + toEscapedPath(dirName));
533              id2 = GetInstrumentId(dstId, dirName);              id2 = GetInstrumentId(dstId, dirName);
534              if (id2 != -1) throw Exception("Instrument with that name exist: " + dirName);              if (id2 != -1) throw Exception("Instrument with that name exist: " + toEscapedPath(dirName));
535    
536              std::stringstream sql;              std::stringstream sql;
537              sql << "UPDATE instr_dirs SET parent_dir_id=" << dstId;              sql << "UPDATE instr_dirs SET parent_dir_id=" << dstId;
# Line 543  namespace LinuxSampler { Line 557  namespace LinuxSampler {
557          BeginTransaction();          BeginTransaction();
558          try {          try {
559              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
560              if (dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
561              int dstId = GetDirectoryId(Dst);              int dstId = GetDirectoryId(Dst);
562              if (dstId == -1) throw Exception("Unknown DB directory: " + Dst);              if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
563              if (dirId == dstId) {              if (dirId == dstId) {
564                  throw Exception("Cannot copy directory to itself");                  throw Exception("Cannot copy directory to itself");
565              }              }
# Line 561  namespace LinuxSampler { Line 575  namespace LinuxSampler {
575              String dirName = GetFileName(Dir);              String dirName = GetFileName(Dir);
576    
577              int id2 = GetDirectoryId(dstId, dirName);              int id2 = GetDirectoryId(dstId, dirName);
578              if (id2 != -1) throw Exception("DB directory already exist: " + dirName);              if (id2 != -1) throw Exception("DB directory already exist: " + toEscapedPath(dirName));
579              id2 = GetInstrumentId(dstId, dirName);              id2 = GetInstrumentId(dstId, dirName);
580              if (id2 != -1) throw Exception("Instrument with that name exist: " + dirName);              if (id2 != -1) throw Exception("Instrument with that name exist: " + toEscapedPath(dirName));
581    
582              DirectoryCopier directoryCopier(ParentDir, Dst);              DirectoryCopier directoryCopier(ParentDir, Dst);
583              DirectoryTreeWalk(Dir, &directoryCopier);              DirectoryTreeWalk(Dir, &directoryCopier);
# Line 581  namespace LinuxSampler { Line 595  namespace LinuxSampler {
595          BeginTransaction();          BeginTransaction();
596          try {          try {
597              int id = GetDirectoryId(Dir);              int id = GetDirectoryId(Dir);
598              if(id == -1) throw Exception("Unknown DB directory: " + Dir);              if(id == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
599    
600              std::stringstream sql;              std::stringstream sql;
601              sql << "UPDATE instr_dirs SET description=?,modified=CURRENT_TIMESTAMP ";              sql << "UPDATE instr_dirs SET description=?,modified=CURRENT_TIMESTAMP ";
# Line 645  namespace LinuxSampler { Line 659  namespace LinuxSampler {
659          DbInstrumentsMutex.Lock();          DbInstrumentsMutex.Lock();
660          try {          try {
661              int dirId = GetDirectoryId(DbDir);              int dirId = GetDirectoryId(DbDir);
662              if (dirId == -1) throw Exception("Invalid DB directory: " + DbDir);              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir));
663    
664              struct stat statBuf;              struct stat statBuf;
665              int res = stat(FilePath.c_str(), &statBuf);              int res = stat(FilePath.c_str(), &statBuf);
# Line 677  namespace LinuxSampler { Line 691  namespace LinuxSampler {
691          DbInstrumentsMutex.Lock();          DbInstrumentsMutex.Lock();
692          try {          try {
693              int dirId = GetDirectoryId(DbDir);              int dirId = GetDirectoryId(DbDir);
694              if (dirId == -1) throw Exception("Invalid DB directory: " + DbDir);              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
695    
696              struct stat statBuf;              struct stat statBuf;
697              int res = stat(FsDir.c_str(), &statBuf);              int res = stat(FsDir.c_str(), &statBuf);
# Line 766  namespace LinuxSampler { Line 780  namespace LinuxSampler {
780          }          }
781          EndTransaction();          EndTransaction();
782    
783          if (i == -1) throw Exception("Unknown Db directory: " + Dir);          if (i == -1) throw Exception("Unknown Db directory: " + toEscapedPath(Dir));
784          return i;          return i;
785      }      }
786    
# Line 782  namespace LinuxSampler { Line 796  namespace LinuxSampler {
796          BeginTransaction();          BeginTransaction();
797          try {          try {
798              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
799              if(dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if(dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
800    
801              StringListPtr pInstrs;              StringListPtr pInstrs;
802    
# Line 796  namespace LinuxSampler { Line 810  namespace LinuxSampler {
810                  sql << "SELECT instr_name FROM instruments WHERE dir_id=" << dirId;                  sql << "SELECT instr_name FROM instruments WHERE dir_id=" << dirId;
811    
812                  pInstrs = ExecSqlStringList(sql.str());                  pInstrs = ExecSqlStringList(sql.str());
813                    // Converting to abstract names
814                    for (int i = 0; i < pInstrs->size(); i++) {
815                        for (int j = 0; j < pInstrs->at(i).length(); j++) {
816                            if (pInstrs->at(i).at(j) == '/') pInstrs->at(i).at(j) = '\0';
817                        }
818                    }
819              }              }
820              EndTransaction();              EndTransaction();
821              return pInstrs;              return pInstrs;
# Line 820  namespace LinuxSampler { Line 840  namespace LinuxSampler {
840          std::stringstream sql;          std::stringstream sql;
841          sql << "SELECT instr_id FROM instruments WHERE dir_id=";          sql << "SELECT instr_id FROM instruments WHERE dir_id=";
842          sql << DirId << " AND instr_name=?";          sql << DirId << " AND instr_name=?";
843          return ExecSqlInt(sql.str(), InstrName);          return ExecSqlInt(sql.str(), toDbName(InstrName));
844      }      }
845    
846      String InstrumentsDb::GetInstrumentName(int InstrId) {      String InstrumentsDb::GetInstrumentName(int InstrId) {
847          dmsg(2,("InstrumentsDb: GetInstrumentName(InstrId=%d)\n", InstrId));          dmsg(2,("InstrumentsDb: GetInstrumentName(InstrId=%d)\n", InstrId));
848          std::stringstream sql;          std::stringstream sql;
849          sql << "SELECT instr_name FROM instruments WHERE instr_id=" << InstrId;          sql << "SELECT instr_name FROM instruments WHERE instr_id=" << InstrId;
850          return ExecSqlString(sql.str());          return toAbstractName(ExecSqlString(sql.str()));
851      }      }
852            
853      void InstrumentsDb::RemoveInstrument(String Instr) {      void InstrumentsDb::RemoveInstrument(String Instr) {
# Line 839  namespace LinuxSampler { Line 859  namespace LinuxSampler {
859          try {          try {
860              int instrId = GetInstrumentId(Instr);              int instrId = GetInstrumentId(Instr);
861              if(instrId == -1) {              if(instrId == -1) {
862                  throw Exception("The specified instrument does not exist: " + Instr);                  throw Exception("The specified instrument does not exist: " + toEscapedPath(Instr));
863              }              }
864              RemoveInstrument(instrId);              RemoveInstrument(instrId);
865          } catch (Exception e) {          } catch (Exception e) {
# Line 874  namespace LinuxSampler { Line 894  namespace LinuxSampler {
894          BeginTransaction();          BeginTransaction();
895          try {          try {
896              int id = GetInstrumentId(Instr);              int id = GetInstrumentId(Instr);
897              if(id == -1) throw Exception("Unknown DB instrument: " + Instr);              if(id == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
898              i = GetInstrumentInfo(id);              i = GetInstrumentInfo(id);
899          } catch (Exception e) {          } catch (Exception e) {
900              EndTransaction();              EndTransaction();
# Line 933  namespace LinuxSampler { Line 953  namespace LinuxSampler {
953          BeginTransaction();          BeginTransaction();
954          try {          try {
955              int dirId = GetDirectoryId(GetDirectoryPath(Instr));              int dirId = GetDirectoryId(GetDirectoryPath(Instr));
956              if (dirId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (dirId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
957    
958              int instrId = GetInstrumentId(dirId, GetFileName(Instr));              int instrId = GetInstrumentId(dirId, GetFileName(Instr));
959              if (instrId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (instrId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
960    
961              if (GetInstrumentId(dirId, Name) != -1) {              if (GetInstrumentId(dirId, Name) != -1) {
962                  throw Exception("Cannot rename. Instrument with that name already exists: " + Name);                  String s = toEscapedPath(Name);
963                    throw Exception("Cannot rename. Instrument with that name already exists: " + s);
964              }              }
965    
966              if (GetDirectoryId(dirId, Name) != -1) {              if (GetDirectoryId(dirId, Name) != -1) {
967                  throw Exception("Cannot rename. Directory with that name already exists: " + Name);                  String s = toEscapedPath(Name);
968                    throw Exception("Cannot rename. Directory with that name already exists: " + s);
969              }              }
970    
971              std::stringstream sql;              std::stringstream sql;
972              sql << "UPDATE instruments SET instr_name=? WHERE instr_id=" << instrId;              sql << "UPDATE instruments SET instr_name=? WHERE instr_id=" << instrId;
973              ExecSql(sql.str(), Name);              ExecSql(sql.str(), toDbName(Name));
974          } catch (Exception e) {          } catch (Exception e) {
975              EndTransaction();              EndTransaction();
976              throw e;              throw e;
977          }          }
978          EndTransaction();          EndTransaction();
979          FireInstrumentNameChanged(Instr, Name);          FireInstrumentNameChanged(Instr, toAbstractName(Name));
980      }      }
981    
982      void InstrumentsDb::MoveInstrument(String Instr, String Dst) {      void InstrumentsDb::MoveInstrument(String Instr, String Dst) {
# Line 964  namespace LinuxSampler { Line 986  namespace LinuxSampler {
986    
987          BeginTransaction();          BeginTransaction();
988          try {          try {
989              int dirId = GetDirectoryId(GetDirectoryPath(Instr));              int dirId = GetDirectoryId(ParentDir);
990              if (dirId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (dirId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
991    
992              String instrName = GetFileName(Instr);              String instrName = GetFileName(Instr);
993              int instrId = GetInstrumentId(dirId, instrName);              int instrId = GetInstrumentId(dirId, instrName);
994              if (instrId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (instrId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
995    
996              int dstId = GetDirectoryId(Dst);              int dstId = GetDirectoryId(Dst);
997              if (dstId == -1) throw Exception("Unknown DB directory: " + Dst);              if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
998              if (dirId == dstId) {              if (dirId == dstId) {
999                  EndTransaction();                  EndTransaction();
1000                  return;                  return;
1001              }              }
1002    
1003              if (GetInstrumentId(dstId, instrName) != -1) {              if (GetInstrumentId(dstId, instrName) != -1) {
1004                  throw Exception("Cannot move. Instrument with that name already exists: " + instrName);                  String s = toEscapedPath(instrName);
1005                    throw Exception("Cannot move. Instrument with that name already exists: " + s);
1006              }              }
1007    
1008              if (GetDirectoryId(dstId, instrName) != -1) {              if (GetDirectoryId(dstId, instrName) != -1) {
1009                  throw Exception("Cannot move. Directory with that name already exists: " + instrName);                  String s = toEscapedPath(instrName);
1010                    throw Exception("Cannot move. Directory with that name already exists: " + s);
1011              }              }
1012    
1013              std::stringstream sql;              std::stringstream sql;
# Line 1007  namespace LinuxSampler { Line 1031  namespace LinuxSampler {
1031          BeginTransaction();          BeginTransaction();
1032          try {          try {
1033              int dirId = GetDirectoryId(GetDirectoryPath(Instr));              int dirId = GetDirectoryId(GetDirectoryPath(Instr));
1034              if (dirId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (dirId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1035    
1036              String instrName = GetFileName(Instr);              String instrName = GetFileName(Instr);
1037              int instrId = GetInstrumentId(dirId, instrName);              int instrId = GetInstrumentId(dirId, instrName);
1038              if (instrId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (instrId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1039    
1040              int dstId = GetDirectoryId(Dst);              int dstId = GetDirectoryId(Dst);
1041              if (dstId == -1) throw Exception("Unknown DB directory: " + Dst);              if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
1042              if (dirId == dstId) {              if (dirId == dstId) {
1043                  EndTransaction();                  EndTransaction();
1044                  return;                  return;
1045              }              }
1046    
             if (GetInstrumentId(dstId, instrName) != -1) {  
                 throw Exception("Cannot copy. Instrument with that name already exists: " + instrName);  
             }  
   
             if (GetDirectoryId(dstId, instrName) != -1) {  
                 throw Exception("Cannot copy. Directory with that name already exists: " + instrName);  
             }  
   
1047              CopyInstrument(instrId, instrName, dstId, Dst);              CopyInstrument(instrId, instrName, dstId, Dst);
1048          } catch (Exception e) {          } catch (Exception e) {
1049              EndTransaction();              EndTransaction();
# Line 1038  namespace LinuxSampler { Line 1054  namespace LinuxSampler {
1054      }      }
1055    
1056      void InstrumentsDb::CopyInstrument(int InstrId, String InstrName, int DstDirId, String DstDir) {      void InstrumentsDb::CopyInstrument(int InstrId, String InstrName, int DstDirId, String DstDir) {
1057            if (GetInstrumentId(DstDirId, InstrName) != -1) {
1058                String s = toEscapedPath(InstrName);
1059                throw Exception("Cannot copy. Instrument with that name already exists: " + s);
1060            }
1061    
1062            if (GetDirectoryId(DstDirId, InstrName) != -1) {
1063                String s = toEscapedPath(InstrName);
1064                throw Exception("Cannot copy. Directory with that name already exists: " + s);
1065            }
1066    
1067          DbInstrument i = GetInstrumentInfo(InstrId);          DbInstrument i = GetInstrumentInfo(InstrId);
1068          sqlite3_stmt *pStmt = NULL;          sqlite3_stmt *pStmt = NULL;
1069          std::stringstream sql;          std::stringstream sql;
# Line 1051  namespace LinuxSampler { Line 1077  namespace LinuxSampler {
1077              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1078          }          }
1079    
1080          BindTextParam(pStmt, 1, InstrName);          String s = toDbName(InstrName);
1081            BindTextParam(pStmt, 1, s);
1082          BindTextParam(pStmt, 2, i.InstrFile);          BindTextParam(pStmt, 2, i.InstrFile);
1083          BindTextParam(pStmt, 3, i.FormatFamily);          BindTextParam(pStmt, 3, i.FormatFamily);
1084          BindTextParam(pStmt, 4, i.FormatVersion);          BindTextParam(pStmt, 4, i.FormatVersion);
# Line 1076  namespace LinuxSampler { Line 1103  namespace LinuxSampler {
1103          BeginTransaction();          BeginTransaction();
1104          try {          try {
1105              int id = GetInstrumentId(Instr);              int id = GetInstrumentId(Instr);
1106              if(id == -1) throw Exception("Unknown DB instrument: " + Instr);              if(id == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1107    
1108              std::stringstream sql;              std::stringstream sql;
1109              sql << "UPDATE instruments SET description=?,modified=CURRENT_TIMESTAMP ";              sql << "UPDATE instruments SET description=?,modified=CURRENT_TIMESTAMP ";
# Line 1117  namespace LinuxSampler { Line 1144  namespace LinuxSampler {
1144      void InstrumentsDb::AddGigInstruments(String DbDir, String File, int Index, ScanProgress* pProgress) {      void InstrumentsDb::AddGigInstruments(String DbDir, String File, int Index, ScanProgress* pProgress) {
1145          dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), File.c_str(), Index));          dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), File.c_str(), Index));
1146          int dirId = GetDirectoryId(DbDir);          int dirId = GetDirectoryId(DbDir);
1147          if (dirId == -1) throw Exception("Invalid DB directory: " + DbDir);          if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
1148    
1149          struct stat statBuf;          struct stat statBuf;
1150          int res = stat(File.c_str(), &statBuf);          int res = stat(File.c_str(), &statBuf);
# Line 1138  namespace LinuxSampler { Line 1165  namespace LinuxSampler {
1165          try {          try {
1166              riff = new RIFF::File(File);              riff = new RIFF::File(File);
1167              gig::File* gig = new gig::File(riff);              gig::File* gig = new gig::File(riff);
1168                gig->SetAutoLoad(false); // avoid time consuming samples scanning
1169    
1170              std::stringstream sql;              std::stringstream sql;
1171              sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,";              sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,";
# Line 1152  namespace LinuxSampler { Line 1180  namespace LinuxSampler {
1180                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1181              }              }
1182    
1183              BindTextParam(pStmt, 2, File);              String s = toEscapedFsPath(File);
1184                BindTextParam(pStmt, 2, s);
1185              String ver = "";              String ver = "";
1186              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);
1187              BindTextParam(pStmt, 4, ver);              BindTextParam(pStmt, 4, ver);
# Line 1211  namespace LinuxSampler { Line 1240  namespace LinuxSampler {
1240          std::stringstream sql2;          std::stringstream sql2;
1241          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";
1242          sql2 << "instr_nr=" << Index;          sql2 << "instr_nr=" << Index;
1243          if (ExecSqlInt(sql2.str(), File) > 0) return;          String s = toEscapedFsPath(File);
1244            if (ExecSqlInt(sql2.str(), s) > 0) return;
1245    
1246          BindTextParam(pStmt, 1, name);          BindTextParam(pStmt, 1, name);
1247          BindIntParam(pStmt, 3, Index);          BindIntParam(pStmt, 3, Index);
# Line 1240  namespace LinuxSampler { Line 1270  namespace LinuxSampler {
1270          FireInstrumentCountChanged(DbDir);          FireInstrumentCountChanged(DbDir);
1271      }      }
1272    
1273      void InstrumentsDb::DirectoryTreeWalk(String Path, DirectoryHandler* pHandler) {      void InstrumentsDb::DirectoryTreeWalk(String AbstractPath, DirectoryHandler* pHandler) {
1274          int DirId = GetDirectoryId(Path);          int DirId = GetDirectoryId(AbstractPath);
1275          if(DirId == -1) throw Exception("Unknown DB directory: " + Path);          if(DirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(AbstractPath));
1276          DirectoryTreeWalk(pHandler, Path, DirId, 0);          DirectoryTreeWalk(pHandler, AbstractPath, DirId, 0);
1277      }      }
1278    
1279      void InstrumentsDb::DirectoryTreeWalk(DirectoryHandler* pHandler, String Path, int DirId, int Level) {      void InstrumentsDb::DirectoryTreeWalk(DirectoryHandler* pHandler, String AbstractPath, int DirId, int Level) {
1280          if(Level == 1000) throw Exception("Possible infinite loop detected");          if(Level == 1000) throw Exception("Possible infinite loop detected");
1281          pHandler->ProcessDirectory(Path, DirId);          pHandler->ProcessDirectory(AbstractPath, DirId);
1282                    
1283          String s;          String s;
1284          StringListPtr pDirs = GetDirectories(DirId);          StringListPtr pDirs = GetDirectories(DirId);
1285          for(int i = 0; i < pDirs->size(); i++) {          for(int i = 0; i < pDirs->size(); i++) {
1286              if (Path.length() == 1 && Path.at(0) == '/') s = "/" + pDirs->at(i);              if (AbstractPath.length() == 1 && AbstractPath.at(0) == '/') {
1287              else s = Path + "/" + pDirs->at(i);                  s = "/" + pDirs->at(i);
1288                } else {
1289                    s = AbstractPath + "/" + pDirs->at(i);
1290                }
1291              DirectoryTreeWalk(pHandler, s, GetDirectoryId(DirId, pDirs->at(i)), Level + 1);              DirectoryTreeWalk(pHandler, s, GetDirectoryId(DirId, pDirs->at(i)), Level + 1);
1292          }          }
1293      }      }
# Line 1266  namespace LinuxSampler { Line 1299  namespace LinuxSampler {
1299          BeginTransaction();          BeginTransaction();
1300          try {          try {
1301              int DirId = GetDirectoryId(Dir);              int DirId = GetDirectoryId(Dir);
1302              if(DirId == -1) throw Exception("Unknown DB directory: " + Dir);              if(DirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
1303    
1304              if (Recursive) DirectoryTreeWalk(Dir, &directoryFinder);              if (Recursive) DirectoryTreeWalk(Dir, &directoryFinder);
1305              else directoryFinder.ProcessDirectory(Dir, DirId);              else directoryFinder.ProcessDirectory(Dir, DirId);
# Line 1286  namespace LinuxSampler { Line 1319  namespace LinuxSampler {
1319          BeginTransaction();          BeginTransaction();
1320          try {          try {
1321              int DirId = GetDirectoryId(Dir);              int DirId = GetDirectoryId(Dir);
1322              if(DirId == -1) throw Exception("Unknown DB directory: " + Dir);              if(DirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
1323    
1324              if (Recursive) DirectoryTreeWalk(Dir, &instrumentFinder);              if (Recursive) DirectoryTreeWalk(Dir, &instrumentFinder);
1325              else instrumentFinder.ProcessDirectory(Dir, DirId);              else instrumentFinder.ProcessDirectory(Dir, DirId);
# Line 1588  namespace LinuxSampler { Line 1621  namespace LinuxSampler {
1621          return Dir.substr(0, i);          return Dir.substr(0, i);
1622      }      }
1623    
1624        void InstrumentsDb::Format() {
1625            DbInstrumentsMutex.Lock();
1626            if (db != NULL) {
1627                sqlite3_close(db);
1628                db = NULL;
1629            }
1630    
1631            if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;
1632            String bkp = DbFile + ".bkp";
1633            remove(bkp.c_str());
1634            if (rename(DbFile.c_str(), bkp.c_str()) && errno != ENOENT) {
1635                DbInstrumentsMutex.Unlock();
1636                throw Exception(String("Failed to backup database: ") + strerror(errno));
1637            }
1638            
1639            String f = DbFile;
1640            DbFile = "";
1641            try { CreateInstrumentsDb(f); }
1642            catch(Exception e) {
1643                DbInstrumentsMutex.Unlock();
1644                throw e;
1645            }
1646            DbInstrumentsMutex.Unlock();
1647            
1648            FireDirectoryCountChanged("/");
1649            FireInstrumentCountChanged("/");
1650        }
1651    
1652      void InstrumentsDb::CheckFileName(String File) {      void InstrumentsDb::CheckFileName(String File) {
1653          if (File.empty()) throw Exception("Invalid file name: " + File);          if (File.empty()) throw Exception("Invalid file name: " + File);
         if (File.find('/') != std::string::npos) {  
             throw Exception("Invalid file name: " + File);  
         }  
1654      }      }
1655    
1656      String InstrumentsDb::GetUniqueInstrumentName(int DirId, String Name) {      String InstrumentsDb::GetUniqueInstrumentName(int DirId, String Name) {
# Line 1611  namespace LinuxSampler { Line 1669  namespace LinuxSampler {
1669          throw Exception("Unable to find an unique name: " + Name);          throw Exception("Unable to find an unique name: " + Name);
1670      }      }
1671    
1672        String InstrumentsDb::toDbName(String AbstractName) {
1673            for (int i = 0; i < AbstractName.length(); i++) {
1674                if (AbstractName.at(i) == '\0') AbstractName.at(i) = '/';
1675            }
1676            return AbstractName;
1677        }
1678    
1679        String InstrumentsDb::toEscapedPath(String AbstractName) {
1680            for (int i = 0; i < AbstractName.length(); i++) {
1681                if (AbstractName.at(i) == '\0')      AbstractName.replace(i++, 1, "\\x2f");
1682                else if (AbstractName.at(i) == '\\') AbstractName.replace(i++, 1, "\\\\");
1683                else if (AbstractName.at(i) == '\'') AbstractName.replace(i++, 1, "\\'");
1684                else if (AbstractName.at(i) == '"')  AbstractName.replace(i++, 1, "\\\"");
1685                else if (AbstractName.at(i) == '\r') AbstractName.replace(i++, 1, "\\r");
1686                else if (AbstractName.at(i) == '\n') AbstractName.replace(i++, 1, "\\n");
1687            }
1688            return AbstractName;
1689        }
1690        
1691        String InstrumentsDb::toEscapedText(String text) {
1692            for (int i = 0; i < text.length(); i++) {
1693                if (text.at(i) == '\\')      text.replace(i++, 1, "\\\\");
1694                else if (text.at(i) == '\'') text.replace(i++, 1, "\\'");
1695                else if (text.at(i) == '"')  text.replace(i++, 1, "\\\"");
1696                else if (text.at(i) == '\r') text.replace(i++, 1, "\\r");
1697                else if (text.at(i) == '\n') text.replace(i++, 1, "\\n");
1698            }
1699            return text;
1700        }
1701        
1702        String InstrumentsDb::toEscapedFsPath(String FsPath) {
1703            return toEscapedText(FsPath);
1704        }
1705        
1706        String InstrumentsDb::toAbstractName(String DbName) {
1707            for (int i = 0; i < DbName.length(); i++) {
1708                if (DbName.at(i) == '/') DbName.at(i) = '\0';
1709            }
1710            return DbName;
1711        }
1712    
1713      void InstrumentsDb::FireDirectoryCountChanged(String Dir) {      void InstrumentsDb::FireDirectoryCountChanged(String Dir) {
1714          for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {          for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {
1715              llInstrumentsDbListeners.GetListener(i)->DirectoryCountChanged(Dir);              llInstrumentsDbListeners.GetListener(i)->DirectoryCountChanged(Dir);
# Line 1654  namespace LinuxSampler { Line 1753  namespace LinuxSampler {
1753      }      }
1754    
1755  } // namespace LinuxSampler  } // namespace LinuxSampler
   
 #endif // HAVE_SQLITE3  

Legend:
Removed from v.1200  
changed lines
  Added in v.1644

  ViewVC Help
Powered by ViewVC