/[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 1642 by nagata, Sun Jan 13 16:36:14 2008 UTC
# 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 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 127  namespace LinuxSampler { Line 127  namespace LinuxSampler {
127      sqlite3* InstrumentsDb::GetDb() {      sqlite3* InstrumentsDb::GetDb() {
128          if ( db != NULL) return db;          if ( db != NULL) return db;
129    
130          if (DbFile.empty()) DbFile = "/var/lib/linuxsampler/instruments.db";          if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;
131                    #if defined(__APPLE__)  /* 20071224 Toshi Nagata  */
132                    if (DbFile.find("~") == 0)
133                            DbFile.replace(0, 1, getenv("HOME"));
134                    #endif
135          int rc = sqlite3_open(DbFile.c_str(), &db);          int rc = sqlite3_open(DbFile.c_str(), &db);
136          if (rc) {          if (rc) {
137              sqlite3_close(db);              sqlite3_close(db);
# Line 136  namespace LinuxSampler { Line 140  namespace LinuxSampler {
140          }          }
141          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);
142          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."); }
143    
144            // TODO: remove this in the next version
145            try {
146                int i = ExecSqlInt("SELECT parent_dir_id FROM instr_dirs WHERE dir_id=0");
147                // The parent ID of the root directory should be -2 now.
148                if(i != -2) ExecSql("UPDATE instr_dirs SET parent_dir_id=-2 WHERE dir_id=0");
149            } catch(Exception e) { }
150            ////////////////////////////////////////
151                    
152          return db;          return db;
153      }      }
# Line 149  namespace LinuxSampler { Line 161  namespace LinuxSampler {
161                    
162          int count = ExecSqlInt(sql.str());          int count = ExecSqlInt(sql.str());
163    
         // 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--;  
164          return count;          return count;
165      }      }
166    
# Line 173  namespace LinuxSampler { Line 182  namespace LinuxSampler {
182              throw e;              throw e;
183          }          }
184          EndTransaction();          EndTransaction();
185          if (i == -1) throw Exception("Unkown DB directory: " + Dir);          if (i == -1) throw Exception("Unkown DB directory: " + toEscapedPath(Dir));
186                    
187          return i;          return i;
188      }      }
# Line 192  namespace LinuxSampler { Line 201  namespace LinuxSampler {
201          BeginTransaction();          BeginTransaction();
202          try {          try {
203              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
204              if(dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if(dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
205    
206              StringListPtr pDirs;              StringListPtr pDirs;
207              if (Recursive) {              if (Recursive) {
# Line 215  namespace LinuxSampler { Line 224  namespace LinuxSampler {
224          std::stringstream sql;          std::stringstream sql;
225          sql << "SELECT dir_name FROM instr_dirs ";          sql << "SELECT dir_name FROM instr_dirs ";
226          sql << "WHERE parent_dir_id=" << DirId << " AND dir_id!=0";          sql << "WHERE parent_dir_id=" << DirId << " AND dir_id!=0";
227          return ExecSqlStringList(sql.str());          StringListPtr dirs = ExecSqlStringList(sql.str());
228    
229            for (int i = 0; i < dirs->size(); i++) {
230                for (int j = 0; j < dirs->at(i).length(); j++) {
231                    if (dirs->at(i).at(j) == '/') dirs->at(i).at(j) = '\0';
232                }
233            }
234    
235            return dirs;
236      }      }
237    
238      int InstrumentsDb::GetDirectoryId(String Dir) {      int InstrumentsDb::GetDirectoryId(String Dir) {
# Line 244  namespace LinuxSampler { Line 261  namespace LinuxSampler {
261    
262      int InstrumentsDb::GetDirectoryId(int ParentDirId, String DirName) {      int InstrumentsDb::GetDirectoryId(int ParentDirId, String DirName) {
263          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()));
264            DirName = toDbName(DirName);
265          std::stringstream sql;          std::stringstream sql;
266          sql << "SELECT dir_id FROM instr_dirs WHERE parent_dir_id=";          sql << "SELECT dir_id FROM instr_dirs WHERE parent_dir_id=";
267          sql << ParentDirId << " AND dir_name=?";          sql << ParentDirId << " AND dir_name=?";
# Line 296  namespace LinuxSampler { Line 314  namespace LinuxSampler {
314    
315              String dirName = GetFileName(Dir);              String dirName = GetFileName(Dir);
316              if(ParentDir.empty() || dirName.empty()) {              if(ParentDir.empty() || dirName.empty()) {
317                  throw Exception("Failed to add DB directory: " + Dir);                  throw Exception("Failed to add DB directory: " + toEscapedPath(Dir));
318              }              }
319    
320              int id = GetDirectoryId(ParentDir);              int id = GetDirectoryId(ParentDir);
321              if (id == -1) throw Exception("DB directory doesn't exist: " + ParentDir);              if (id == -1) throw Exception("DB directory doesn't exist: " + toEscapedPath(ParentDir));
322              int id2 = GetDirectoryId(id, dirName);              int id2 = GetDirectoryId(id, dirName);
323              if (id2 != -1) throw Exception("DB directory already exist: " + Dir);              if (id2 != -1) throw Exception("DB directory already exist: " + toEscapedPath(Dir));
324              id2 = GetInstrumentId(id, dirName);              id2 = GetInstrumentId(id, dirName);
325              if (id2 != -1) throw Exception("Instrument with that name exist: " + Dir);              if (id2 != -1) throw Exception("Instrument with that name exist: " + toEscapedPath(Dir));
326    
327              std::stringstream sql;              std::stringstream sql;
328              sql << "INSERT INTO instr_dirs (parent_dir_id, dir_name) VALUES (";              sql << "INSERT INTO instr_dirs (parent_dir_id, dir_name) VALUES (";
329              sql << id << ", ?)";              sql << id << ", ?)";
330    
331              ExecSql(sql.str(), dirName);              ExecSql(sql.str(), toDbName(dirName));
332          } catch (Exception e) {          } catch (Exception e) {
333              EndTransaction();              EndTransaction();
334              throw e;              throw e;
# Line 329  namespace LinuxSampler { Line 347  namespace LinuxSampler {
347          BeginTransaction();          BeginTransaction();
348          try {          try {
349              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
350              if (dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
351              if (dirId == 0) throw Exception("Cannot delete the root directory: " + Dir);              if (dirId == 0) throw Exception("Cannot delete the root directory: " + Dir);
352              if(ParentDir.empty()) throw Exception("Unknown parent directory");              if(ParentDir.empty()) throw Exception("Unknown parent directory");
353              if (Force) RemoveDirectoryContent(dirId);              if (Force) RemoveDirectoryContent(dirId);
# Line 416  namespace LinuxSampler { Line 434  namespace LinuxSampler {
434    
435          try {          try {
436              int id = GetDirectoryId(Dir);              int id = GetDirectoryId(Dir);
437              if(id == -1) throw Exception("Unknown DB directory: " + Dir);              if(id == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
438    
439              sqlite3_stmt *pStmt = NULL;              sqlite3_stmt *pStmt = NULL;
440              std::stringstream sql;              std::stringstream sql;
# Line 439  namespace LinuxSampler { Line 457  namespace LinuxSampler {
457                  if (res != SQLITE_DONE) {                  if (res != SQLITE_DONE) {
458                      throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));                      throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
459                  } else {                  } else {
460                      throw Exception("Unknown DB directory: " + Dir);                      throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
461                  }                  }
462              }              }
463                            
# Line 456  namespace LinuxSampler { Line 474  namespace LinuxSampler {
474      void InstrumentsDb::RenameDirectory(String Dir, String Name) {      void InstrumentsDb::RenameDirectory(String Dir, String Name) {
475          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()));
476          CheckFileName(Name);          CheckFileName(Name);
477            String dbName = toDbName(Name);
478    
479          BeginTransaction();          BeginTransaction();
480          try {          try {
481              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
482              if (dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedText(Dir));
483    
484              std::stringstream sql;              std::stringstream sql;
485              sql << "SELECT parent_dir_id FROM instr_dirs WHERE dir_id=" <<  dirId;              sql << "SELECT parent_dir_id FROM instr_dirs WHERE dir_id=" <<  dirId;
486    
487              int parent = ExecSqlInt(sql.str());              int parent = ExecSqlInt(sql.str());
488              if (parent == -1) throw Exception("Unknown parent directory: " + Dir);              if (parent == -1) throw Exception("Unknown parent directory: " + toEscapedPath(Dir));
489              if (GetDirectoryId(parent, Name) != -1) {  
490                  throw Exception("Cannot rename. Directory with that name already exists: " + Name);              if (GetDirectoryId(parent, dbName) != -1) {
491                    String s = toEscapedPath(Name);
492                    throw Exception("Cannot rename. Directory with that name already exists: " + s);
493              }              }
494    
495              if (GetInstrumentId(parent, Name) != -1) {              if (GetInstrumentId(parent, dbName) != -1) {
496                  throw Exception("Cannot rename. Instrument with that name exist: " + Dir);                  throw Exception("Cannot rename. Instrument with that name exist: " + toEscapedPath(Dir));
497              }              }
498    
499              sql.str("");              sql.str("");
500              sql << "UPDATE instr_dirs SET dir_name=? WHERE dir_id=" << dirId;              sql << "UPDATE instr_dirs SET dir_name=? WHERE dir_id=" << dirId;
501              ExecSql(sql.str(), Name);              ExecSql(sql.str(), dbName);
502          } catch (Exception e) {          } catch (Exception e) {
503              EndTransaction();              EndTransaction();
504              throw e;              throw e;
505          }          }
506    
507          EndTransaction();          EndTransaction();
508          FireDirectoryNameChanged(Dir, Name);          FireDirectoryNameChanged(Dir, toAbstractName(Name));
509      }      }
510    
511      void InstrumentsDb::MoveDirectory(String Dir, String Dst) {      void InstrumentsDb::MoveDirectory(String Dir, String Dst) {
# Line 497  namespace LinuxSampler { Line 518  namespace LinuxSampler {
518          BeginTransaction();          BeginTransaction();
519          try {          try {
520              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
521              if (dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
522              int dstId = GetDirectoryId(Dst);              int dstId = GetDirectoryId(Dst);
523              if (dstId == -1) throw Exception("Unknown DB directory: " + Dst);              if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
524              if (dirId == dstId) {              if (dirId == dstId) {
525                  throw Exception("Cannot move directory to itself");                  throw Exception("Cannot move directory to itself");
526              }              }
# Line 515  namespace LinuxSampler { Line 536  namespace LinuxSampler {
536              String dirName = GetFileName(Dir);              String dirName = GetFileName(Dir);
537    
538              int id2 = GetDirectoryId(dstId, dirName);              int id2 = GetDirectoryId(dstId, dirName);
539              if (id2 != -1) throw Exception("DB directory already exist: " + dirName);              if (id2 != -1) throw Exception("DB directory already exist: " + toEscapedPath(dirName));
540              id2 = GetInstrumentId(dstId, dirName);              id2 = GetInstrumentId(dstId, dirName);
541              if (id2 != -1) throw Exception("Instrument with that name exist: " + dirName);              if (id2 != -1) throw Exception("Instrument with that name exist: " + toEscapedPath(dirName));
542    
543              std::stringstream sql;              std::stringstream sql;
544              sql << "UPDATE instr_dirs SET parent_dir_id=" << dstId;              sql << "UPDATE instr_dirs SET parent_dir_id=" << dstId;
# Line 543  namespace LinuxSampler { Line 564  namespace LinuxSampler {
564          BeginTransaction();          BeginTransaction();
565          try {          try {
566              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
567              if (dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
568              int dstId = GetDirectoryId(Dst);              int dstId = GetDirectoryId(Dst);
569              if (dstId == -1) throw Exception("Unknown DB directory: " + Dst);              if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
570              if (dirId == dstId) {              if (dirId == dstId) {
571                  throw Exception("Cannot copy directory to itself");                  throw Exception("Cannot copy directory to itself");
572              }              }
# Line 561  namespace LinuxSampler { Line 582  namespace LinuxSampler {
582              String dirName = GetFileName(Dir);              String dirName = GetFileName(Dir);
583    
584              int id2 = GetDirectoryId(dstId, dirName);              int id2 = GetDirectoryId(dstId, dirName);
585              if (id2 != -1) throw Exception("DB directory already exist: " + dirName);              if (id2 != -1) throw Exception("DB directory already exist: " + toEscapedPath(dirName));
586              id2 = GetInstrumentId(dstId, dirName);              id2 = GetInstrumentId(dstId, dirName);
587              if (id2 != -1) throw Exception("Instrument with that name exist: " + dirName);              if (id2 != -1) throw Exception("Instrument with that name exist: " + toEscapedPath(dirName));
588    
589              DirectoryCopier directoryCopier(ParentDir, Dst);              DirectoryCopier directoryCopier(ParentDir, Dst);
590              DirectoryTreeWalk(Dir, &directoryCopier);              DirectoryTreeWalk(Dir, &directoryCopier);
# Line 581  namespace LinuxSampler { Line 602  namespace LinuxSampler {
602          BeginTransaction();          BeginTransaction();
603          try {          try {
604              int id = GetDirectoryId(Dir);              int id = GetDirectoryId(Dir);
605              if(id == -1) throw Exception("Unknown DB directory: " + Dir);              if(id == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
606    
607              std::stringstream sql;              std::stringstream sql;
608              sql << "UPDATE instr_dirs SET description=?,modified=CURRENT_TIMESTAMP ";              sql << "UPDATE instr_dirs SET description=?,modified=CURRENT_TIMESTAMP ";
# Line 645  namespace LinuxSampler { Line 666  namespace LinuxSampler {
666          DbInstrumentsMutex.Lock();          DbInstrumentsMutex.Lock();
667          try {          try {
668              int dirId = GetDirectoryId(DbDir);              int dirId = GetDirectoryId(DbDir);
669              if (dirId == -1) throw Exception("Invalid DB directory: " + DbDir);              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir));
670    
671              struct stat statBuf;              struct stat statBuf;
672              int res = stat(FilePath.c_str(), &statBuf);              int res = stat(FilePath.c_str(), &statBuf);
# Line 677  namespace LinuxSampler { Line 698  namespace LinuxSampler {
698          DbInstrumentsMutex.Lock();          DbInstrumentsMutex.Lock();
699          try {          try {
700              int dirId = GetDirectoryId(DbDir);              int dirId = GetDirectoryId(DbDir);
701              if (dirId == -1) throw Exception("Invalid DB directory: " + DbDir);              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
702    
703              struct stat statBuf;              struct stat statBuf;
704              int res = stat(FsDir.c_str(), &statBuf);              int res = stat(FsDir.c_str(), &statBuf);
# Line 766  namespace LinuxSampler { Line 787  namespace LinuxSampler {
787          }          }
788          EndTransaction();          EndTransaction();
789    
790          if (i == -1) throw Exception("Unknown Db directory: " + Dir);          if (i == -1) throw Exception("Unknown Db directory: " + toEscapedPath(Dir));
791          return i;          return i;
792      }      }
793    
# Line 782  namespace LinuxSampler { Line 803  namespace LinuxSampler {
803          BeginTransaction();          BeginTransaction();
804          try {          try {
805              int dirId = GetDirectoryId(Dir);              int dirId = GetDirectoryId(Dir);
806              if(dirId == -1) throw Exception("Unknown DB directory: " + Dir);              if(dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
807    
808              StringListPtr pInstrs;              StringListPtr pInstrs;
809    
# Line 796  namespace LinuxSampler { Line 817  namespace LinuxSampler {
817                  sql << "SELECT instr_name FROM instruments WHERE dir_id=" << dirId;                  sql << "SELECT instr_name FROM instruments WHERE dir_id=" << dirId;
818    
819                  pInstrs = ExecSqlStringList(sql.str());                  pInstrs = ExecSqlStringList(sql.str());
820                    // Converting to abstract names
821                    for (int i = 0; i < pInstrs->size(); i++) {
822                        for (int j = 0; j < pInstrs->at(i).length(); j++) {
823                            if (pInstrs->at(i).at(j) == '/') pInstrs->at(i).at(j) = '\0';
824                        }
825                    }
826              }              }
827              EndTransaction();              EndTransaction();
828              return pInstrs;              return pInstrs;
# Line 820  namespace LinuxSampler { Line 847  namespace LinuxSampler {
847          std::stringstream sql;          std::stringstream sql;
848          sql << "SELECT instr_id FROM instruments WHERE dir_id=";          sql << "SELECT instr_id FROM instruments WHERE dir_id=";
849          sql << DirId << " AND instr_name=?";          sql << DirId << " AND instr_name=?";
850          return ExecSqlInt(sql.str(), InstrName);          return ExecSqlInt(sql.str(), toDbName(InstrName));
851      }      }
852    
853      String InstrumentsDb::GetInstrumentName(int InstrId) {      String InstrumentsDb::GetInstrumentName(int InstrId) {
854          dmsg(2,("InstrumentsDb: GetInstrumentName(InstrId=%d)\n", InstrId));          dmsg(2,("InstrumentsDb: GetInstrumentName(InstrId=%d)\n", InstrId));
855          std::stringstream sql;          std::stringstream sql;
856          sql << "SELECT instr_name FROM instruments WHERE instr_id=" << InstrId;          sql << "SELECT instr_name FROM instruments WHERE instr_id=" << InstrId;
857          return ExecSqlString(sql.str());          return toAbstractName(ExecSqlString(sql.str()));
858      }      }
859            
860      void InstrumentsDb::RemoveInstrument(String Instr) {      void InstrumentsDb::RemoveInstrument(String Instr) {
# Line 839  namespace LinuxSampler { Line 866  namespace LinuxSampler {
866          try {          try {
867              int instrId = GetInstrumentId(Instr);              int instrId = GetInstrumentId(Instr);
868              if(instrId == -1) {              if(instrId == -1) {
869                  throw Exception("The specified instrument does not exist: " + Instr);                  throw Exception("The specified instrument does not exist: " + toEscapedPath(Instr));
870              }              }
871              RemoveInstrument(instrId);              RemoveInstrument(instrId);
872          } catch (Exception e) {          } catch (Exception e) {
# Line 874  namespace LinuxSampler { Line 901  namespace LinuxSampler {
901          BeginTransaction();          BeginTransaction();
902          try {          try {
903              int id = GetInstrumentId(Instr);              int id = GetInstrumentId(Instr);
904              if(id == -1) throw Exception("Unknown DB instrument: " + Instr);              if(id == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
905              i = GetInstrumentInfo(id);              i = GetInstrumentInfo(id);
906          } catch (Exception e) {          } catch (Exception e) {
907              EndTransaction();              EndTransaction();
# Line 933  namespace LinuxSampler { Line 960  namespace LinuxSampler {
960          BeginTransaction();          BeginTransaction();
961          try {          try {
962              int dirId = GetDirectoryId(GetDirectoryPath(Instr));              int dirId = GetDirectoryId(GetDirectoryPath(Instr));
963              if (dirId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (dirId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
964    
965              int instrId = GetInstrumentId(dirId, GetFileName(Instr));              int instrId = GetInstrumentId(dirId, GetFileName(Instr));
966              if (instrId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (instrId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
967    
968              if (GetInstrumentId(dirId, Name) != -1) {              if (GetInstrumentId(dirId, Name) != -1) {
969                  throw Exception("Cannot rename. Instrument with that name already exists: " + Name);                  String s = toEscapedPath(Name);
970                    throw Exception("Cannot rename. Instrument with that name already exists: " + s);
971              }              }
972    
973              if (GetDirectoryId(dirId, Name) != -1) {              if (GetDirectoryId(dirId, Name) != -1) {
974                  throw Exception("Cannot rename. Directory with that name already exists: " + Name);                  String s = toEscapedPath(Name);
975                    throw Exception("Cannot rename. Directory with that name already exists: " + s);
976              }              }
977    
978              std::stringstream sql;              std::stringstream sql;
979              sql << "UPDATE instruments SET instr_name=? WHERE instr_id=" << instrId;              sql << "UPDATE instruments SET instr_name=? WHERE instr_id=" << instrId;
980              ExecSql(sql.str(), Name);              ExecSql(sql.str(), toDbName(Name));
981          } catch (Exception e) {          } catch (Exception e) {
982              EndTransaction();              EndTransaction();
983              throw e;              throw e;
984          }          }
985          EndTransaction();          EndTransaction();
986          FireInstrumentNameChanged(Instr, Name);          FireInstrumentNameChanged(Instr, toAbstractName(Name));
987      }      }
988    
989      void InstrumentsDb::MoveInstrument(String Instr, String Dst) {      void InstrumentsDb::MoveInstrument(String Instr, String Dst) {
# Line 964  namespace LinuxSampler { Line 993  namespace LinuxSampler {
993    
994          BeginTransaction();          BeginTransaction();
995          try {          try {
996              int dirId = GetDirectoryId(GetDirectoryPath(Instr));              int dirId = GetDirectoryId(ParentDir);
997              if (dirId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (dirId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
998    
999              String instrName = GetFileName(Instr);              String instrName = GetFileName(Instr);
1000              int instrId = GetInstrumentId(dirId, instrName);              int instrId = GetInstrumentId(dirId, instrName);
1001              if (instrId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (instrId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1002    
1003              int dstId = GetDirectoryId(Dst);              int dstId = GetDirectoryId(Dst);
1004              if (dstId == -1) throw Exception("Unknown DB directory: " + Dst);              if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
1005              if (dirId == dstId) {              if (dirId == dstId) {
1006                  EndTransaction();                  EndTransaction();
1007                  return;                  return;
1008              }              }
1009    
1010              if (GetInstrumentId(dstId, instrName) != -1) {              if (GetInstrumentId(dstId, instrName) != -1) {
1011                  throw Exception("Cannot move. Instrument with that name already exists: " + instrName);                  String s = toEscapedPath(instrName);
1012                    throw Exception("Cannot move. Instrument with that name already exists: " + s);
1013              }              }
1014    
1015              if (GetDirectoryId(dstId, instrName) != -1) {              if (GetDirectoryId(dstId, instrName) != -1) {
1016                  throw Exception("Cannot move. Directory with that name already exists: " + instrName);                  String s = toEscapedPath(instrName);
1017                    throw Exception("Cannot move. Directory with that name already exists: " + s);
1018              }              }
1019    
1020              std::stringstream sql;              std::stringstream sql;
# Line 1007  namespace LinuxSampler { Line 1038  namespace LinuxSampler {
1038          BeginTransaction();          BeginTransaction();
1039          try {          try {
1040              int dirId = GetDirectoryId(GetDirectoryPath(Instr));              int dirId = GetDirectoryId(GetDirectoryPath(Instr));
1041              if (dirId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (dirId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1042    
1043              String instrName = GetFileName(Instr);              String instrName = GetFileName(Instr);
1044              int instrId = GetInstrumentId(dirId, instrName);              int instrId = GetInstrumentId(dirId, instrName);
1045              if (instrId == -1) throw Exception("Unknown DB instrument: " + Instr);              if (instrId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1046    
1047              int dstId = GetDirectoryId(Dst);              int dstId = GetDirectoryId(Dst);
1048              if (dstId == -1) throw Exception("Unknown DB directory: " + Dst);              if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
1049              if (dirId == dstId) {              if (dirId == dstId) {
1050                  EndTransaction();                  EndTransaction();
1051                  return;                  return;
1052              }              }
1053    
             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);  
             }  
   
1054              CopyInstrument(instrId, instrName, dstId, Dst);              CopyInstrument(instrId, instrName, dstId, Dst);
1055          } catch (Exception e) {          } catch (Exception e) {
1056              EndTransaction();              EndTransaction();
# Line 1038  namespace LinuxSampler { Line 1061  namespace LinuxSampler {
1061      }      }
1062    
1063      void InstrumentsDb::CopyInstrument(int InstrId, String InstrName, int DstDirId, String DstDir) {      void InstrumentsDb::CopyInstrument(int InstrId, String InstrName, int DstDirId, String DstDir) {
1064            if (GetInstrumentId(DstDirId, InstrName) != -1) {
1065                String s = toEscapedPath(InstrName);
1066                throw Exception("Cannot copy. Instrument with that name already exists: " + s);
1067            }
1068    
1069            if (GetDirectoryId(DstDirId, InstrName) != -1) {
1070                String s = toEscapedPath(InstrName);
1071                throw Exception("Cannot copy. Directory with that name already exists: " + s);
1072            }
1073    
1074          DbInstrument i = GetInstrumentInfo(InstrId);          DbInstrument i = GetInstrumentInfo(InstrId);
1075          sqlite3_stmt *pStmt = NULL;          sqlite3_stmt *pStmt = NULL;
1076          std::stringstream sql;          std::stringstream sql;
# Line 1051  namespace LinuxSampler { Line 1084  namespace LinuxSampler {
1084              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1085          }          }
1086    
1087          BindTextParam(pStmt, 1, InstrName);          String s = toDbName(InstrName);
1088            BindTextParam(pStmt, 1, s);
1089          BindTextParam(pStmt, 2, i.InstrFile);          BindTextParam(pStmt, 2, i.InstrFile);
1090          BindTextParam(pStmt, 3, i.FormatFamily);          BindTextParam(pStmt, 3, i.FormatFamily);
1091          BindTextParam(pStmt, 4, i.FormatVersion);          BindTextParam(pStmt, 4, i.FormatVersion);
# Line 1076  namespace LinuxSampler { Line 1110  namespace LinuxSampler {
1110          BeginTransaction();          BeginTransaction();
1111          try {          try {
1112              int id = GetInstrumentId(Instr);              int id = GetInstrumentId(Instr);
1113              if(id == -1) throw Exception("Unknown DB instrument: " + Instr);              if(id == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1114    
1115              std::stringstream sql;              std::stringstream sql;
1116              sql << "UPDATE instruments SET description=?,modified=CURRENT_TIMESTAMP ";              sql << "UPDATE instruments SET description=?,modified=CURRENT_TIMESTAMP ";
# Line 1117  namespace LinuxSampler { Line 1151  namespace LinuxSampler {
1151      void InstrumentsDb::AddGigInstruments(String DbDir, String File, int Index, ScanProgress* pProgress) {      void InstrumentsDb::AddGigInstruments(String DbDir, String File, int Index, ScanProgress* pProgress) {
1152          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));
1153          int dirId = GetDirectoryId(DbDir);          int dirId = GetDirectoryId(DbDir);
1154          if (dirId == -1) throw Exception("Invalid DB directory: " + DbDir);          if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
1155    
1156          struct stat statBuf;          struct stat statBuf;
1157          int res = stat(File.c_str(), &statBuf);          int res = stat(File.c_str(), &statBuf);
# Line 1138  namespace LinuxSampler { Line 1172  namespace LinuxSampler {
1172          try {          try {
1173              riff = new RIFF::File(File);              riff = new RIFF::File(File);
1174              gig::File* gig = new gig::File(riff);              gig::File* gig = new gig::File(riff);
1175                gig->SetAutoLoad(false); // avoid time consuming samples scanning
1176    
1177              std::stringstream sql;              std::stringstream sql;
1178              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 1187  namespace LinuxSampler {
1187                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1188              }              }
1189    
1190              BindTextParam(pStmt, 2, File);              String s = toEscapedFsPath(File);
1191                BindTextParam(pStmt, 2, s);
1192              String ver = "";              String ver = "";
1193              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);
1194              BindTextParam(pStmt, 4, ver);              BindTextParam(pStmt, 4, ver);
# Line 1211  namespace LinuxSampler { Line 1247  namespace LinuxSampler {
1247          std::stringstream sql2;          std::stringstream sql2;
1248          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";
1249          sql2 << "instr_nr=" << Index;          sql2 << "instr_nr=" << Index;
1250          if (ExecSqlInt(sql2.str(), File) > 0) return;          String s = toEscapedFsPath(File);
1251            if (ExecSqlInt(sql2.str(), s) > 0) return;
1252    
1253          BindTextParam(pStmt, 1, name);          BindTextParam(pStmt, 1, name);
1254          BindIntParam(pStmt, 3, Index);          BindIntParam(pStmt, 3, Index);
# Line 1240  namespace LinuxSampler { Line 1277  namespace LinuxSampler {
1277          FireInstrumentCountChanged(DbDir);          FireInstrumentCountChanged(DbDir);
1278      }      }
1279    
1280      void InstrumentsDb::DirectoryTreeWalk(String Path, DirectoryHandler* pHandler) {      void InstrumentsDb::DirectoryTreeWalk(String AbstractPath, DirectoryHandler* pHandler) {
1281          int DirId = GetDirectoryId(Path);          int DirId = GetDirectoryId(AbstractPath);
1282          if(DirId == -1) throw Exception("Unknown DB directory: " + Path);          if(DirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(AbstractPath));
1283          DirectoryTreeWalk(pHandler, Path, DirId, 0);          DirectoryTreeWalk(pHandler, AbstractPath, DirId, 0);
1284      }      }
1285    
1286      void InstrumentsDb::DirectoryTreeWalk(DirectoryHandler* pHandler, String Path, int DirId, int Level) {      void InstrumentsDb::DirectoryTreeWalk(DirectoryHandler* pHandler, String AbstractPath, int DirId, int Level) {
1287          if(Level == 1000) throw Exception("Possible infinite loop detected");          if(Level == 1000) throw Exception("Possible infinite loop detected");
1288          pHandler->ProcessDirectory(Path, DirId);          pHandler->ProcessDirectory(AbstractPath, DirId);
1289                    
1290          String s;          String s;
1291          StringListPtr pDirs = GetDirectories(DirId);          StringListPtr pDirs = GetDirectories(DirId);
1292          for(int i = 0; i < pDirs->size(); i++) {          for(int i = 0; i < pDirs->size(); i++) {
1293              if (Path.length() == 1 && Path.at(0) == '/') s = "/" + pDirs->at(i);              if (AbstractPath.length() == 1 && AbstractPath.at(0) == '/') {
1294              else s = Path + "/" + pDirs->at(i);                  s = "/" + pDirs->at(i);
1295                } else {
1296                    s = AbstractPath + "/" + pDirs->at(i);
1297                }
1298              DirectoryTreeWalk(pHandler, s, GetDirectoryId(DirId, pDirs->at(i)), Level + 1);              DirectoryTreeWalk(pHandler, s, GetDirectoryId(DirId, pDirs->at(i)), Level + 1);
1299          }          }
1300      }      }
# Line 1266  namespace LinuxSampler { Line 1306  namespace LinuxSampler {
1306          BeginTransaction();          BeginTransaction();
1307          try {          try {
1308              int DirId = GetDirectoryId(Dir);              int DirId = GetDirectoryId(Dir);
1309              if(DirId == -1) throw Exception("Unknown DB directory: " + Dir);              if(DirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
1310    
1311              if (Recursive) DirectoryTreeWalk(Dir, &directoryFinder);              if (Recursive) DirectoryTreeWalk(Dir, &directoryFinder);
1312              else directoryFinder.ProcessDirectory(Dir, DirId);              else directoryFinder.ProcessDirectory(Dir, DirId);
# Line 1286  namespace LinuxSampler { Line 1326  namespace LinuxSampler {
1326          BeginTransaction();          BeginTransaction();
1327          try {          try {
1328              int DirId = GetDirectoryId(Dir);              int DirId = GetDirectoryId(Dir);
1329              if(DirId == -1) throw Exception("Unknown DB directory: " + Dir);              if(DirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
1330    
1331              if (Recursive) DirectoryTreeWalk(Dir, &instrumentFinder);              if (Recursive) DirectoryTreeWalk(Dir, &instrumentFinder);
1332              else instrumentFinder.ProcessDirectory(Dir, DirId);              else instrumentFinder.ProcessDirectory(Dir, DirId);
# Line 1588  namespace LinuxSampler { Line 1628  namespace LinuxSampler {
1628          return Dir.substr(0, i);          return Dir.substr(0, i);
1629      }      }
1630    
1631        void InstrumentsDb::Format() {
1632            DbInstrumentsMutex.Lock();
1633            if (db != NULL) {
1634                sqlite3_close(db);
1635                db = NULL;
1636            }
1637    
1638            if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;
1639            String bkp = DbFile + ".bkp";
1640            remove(bkp.c_str());
1641            if (rename(DbFile.c_str(), bkp.c_str()) && errno != ENOENT) {
1642                DbInstrumentsMutex.Unlock();
1643                throw Exception(String("Failed to backup database: ") + strerror(errno));
1644            }
1645            
1646            String f = DbFile;
1647            DbFile = "";
1648            try { CreateInstrumentsDb(f); }
1649            catch(Exception e) {
1650                DbInstrumentsMutex.Unlock();
1651                throw e;
1652            }
1653            DbInstrumentsMutex.Unlock();
1654            
1655            FireDirectoryCountChanged("/");
1656            FireInstrumentCountChanged("/");
1657        }
1658    
1659      void InstrumentsDb::CheckFileName(String File) {      void InstrumentsDb::CheckFileName(String File) {
1660          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);  
         }  
1661      }      }
1662    
1663      String InstrumentsDb::GetUniqueInstrumentName(int DirId, String Name) {      String InstrumentsDb::GetUniqueInstrumentName(int DirId, String Name) {
# Line 1611  namespace LinuxSampler { Line 1676  namespace LinuxSampler {
1676          throw Exception("Unable to find an unique name: " + Name);          throw Exception("Unable to find an unique name: " + Name);
1677      }      }
1678    
1679        String InstrumentsDb::toDbName(String AbstractName) {
1680            for (int i = 0; i < AbstractName.length(); i++) {
1681                if (AbstractName.at(i) == '\0') AbstractName.at(i) = '/';
1682            }
1683            return AbstractName;
1684        }
1685    
1686        String InstrumentsDb::toEscapedPath(String AbstractName) {
1687            for (int i = 0; i < AbstractName.length(); i++) {
1688                if (AbstractName.at(i) == '\0')      AbstractName.replace(i++, 1, "\\x2f");
1689                else if (AbstractName.at(i) == '\\') AbstractName.replace(i++, 1, "\\\\");
1690                else if (AbstractName.at(i) == '\'') AbstractName.replace(i++, 1, "\\'");
1691                else if (AbstractName.at(i) == '"')  AbstractName.replace(i++, 1, "\\\"");
1692                else if (AbstractName.at(i) == '\r') AbstractName.replace(i++, 1, "\\r");
1693                else if (AbstractName.at(i) == '\n') AbstractName.replace(i++, 1, "\\n");
1694            }
1695            return AbstractName;
1696        }
1697        
1698        String InstrumentsDb::toEscapedText(String text) {
1699            for (int i = 0; i < text.length(); i++) {
1700                if (text.at(i) == '\\')      text.replace(i++, 1, "\\\\");
1701                else if (text.at(i) == '\'') text.replace(i++, 1, "\\'");
1702                else if (text.at(i) == '"')  text.replace(i++, 1, "\\\"");
1703                else if (text.at(i) == '\r') text.replace(i++, 1, "\\r");
1704                else if (text.at(i) == '\n') text.replace(i++, 1, "\\n");
1705            }
1706            return text;
1707        }
1708        
1709        String InstrumentsDb::toEscapedFsPath(String FsPath) {
1710            return toEscapedText(FsPath);
1711        }
1712        
1713        String InstrumentsDb::toAbstractName(String DbName) {
1714            for (int i = 0; i < DbName.length(); i++) {
1715                if (DbName.at(i) == '/') DbName.at(i) = '\0';
1716            }
1717            return DbName;
1718        }
1719    
1720      void InstrumentsDb::FireDirectoryCountChanged(String Dir) {      void InstrumentsDb::FireDirectoryCountChanged(String Dir) {
1721          for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {          for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {
1722              llInstrumentsDbListeners.GetListener(i)->DirectoryCountChanged(Dir);              llInstrumentsDbListeners.GetListener(i)->DirectoryCountChanged(Dir);
# Line 1654  namespace LinuxSampler { Line 1760  namespace LinuxSampler {
1760      }      }
1761    
1762  } // namespace LinuxSampler  } // namespace LinuxSampler
   
 #endif // HAVE_SQLITE3  

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

  ViewVC Help
Powered by ViewVC