/[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 1944 by persson, Tue Jul 14 18:54:08 2009 UTC revision 3092 by schoenebeck, Mon Jan 16 22:02:36 2017 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2007-2009 Grigor Iliev, Benno Senoner                   *   *   Copyright (C) 2007-2013 Grigor Iliev, Benno Senoner                   *
4   *                                                                         *   *                                                                         *
5   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
6   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 41  namespace LinuxSampler { Line 41  namespace LinuxSampler {
41      InstrumentsDb InstrumentsDb::instance;      InstrumentsDb InstrumentsDb::instance;
42    
43      void InstrumentsDb::CreateInstrumentsDb(String FilePath) {      void InstrumentsDb::CreateInstrumentsDb(String FilePath) {
44            if (FilePath.empty()) {
45                FilePath = GetDefaultDBLocation();
46                dmsg(0,("InstrumentsDb: Creating database at default location '%s'\n", FilePath.c_str()));
47            }
48    
49          File f = File(FilePath);          File f = File(FilePath);
50          if (f.Exist()) {          if (f.Exist()) {
51              throw Exception("File exists: " + FilePath);              throw Exception("File exists: " + FilePath);
52          }          }
53            
54          GetInstrumentsDb()->SetDbFile(FilePath);          SetDbFile(FilePath);
55    
56          String sql =          String sql =
57              "  CREATE TABLE instr_dirs (                                      "              "  CREATE TABLE instr_dirs (                                      "
# Line 60  namespace LinuxSampler { Line 65  namespace LinuxSampler {
65              "      UNIQUE (parent_dir_id,dir_name)                            "              "      UNIQUE (parent_dir_id,dir_name)                            "
66              "  );                                                             ";              "  );                                                             ";
67                    
68          GetInstrumentsDb()->ExecSql(sql);          ExecSql(sql);
69    
70          sql = "INSERT INTO instr_dirs (dir_id, parent_dir_id, dir_name) VALUES (0, -2, '/');";          sql = "INSERT INTO instr_dirs (dir_id, parent_dir_id, dir_name) VALUES (0, -2, '/');";
71          GetInstrumentsDb()->ExecSql(sql);          ExecSql(sql);
72    
73          sql =          sql =
74              "  CREATE TABLE instruments (                                "              "  CREATE TABLE instruments (                                "
# Line 86  namespace LinuxSampler { Line 91  namespace LinuxSampler {
91              "      UNIQUE (dir_id,instr_name)                            "              "      UNIQUE (dir_id,instr_name)                            "
92              "  );                                                        ";              "  );                                                        ";
93                    
94          GetInstrumentsDb()->ExecSql(sql);          ExecSql(sql);
95      }      }
96    
97      InstrumentsDb::InstrumentsDb() {      InstrumentsDb::InstrumentsDb() {
# Line 111  namespace LinuxSampler { Line 116  namespace LinuxSampler {
116      }      }
117            
118      void InstrumentsDb::SetDbFile(String File) {      void InstrumentsDb::SetDbFile(String File) {
119          DbInstrumentsMutex.Lock();          LockGuard lock(DbInstrumentsMutex);
120          if (File.empty() || DbFile.length() > 0) {          if (File.empty() || DbFile.length() > 0) {
             DbInstrumentsMutex.Unlock();  
121              throw Exception("Failed to set the database file");              throw Exception("Failed to set the database file");
122          }          }
123          DbFile = File;          DbFile = File;
         DbInstrumentsMutex.Unlock();  
124      }      }
125    
126      sqlite3* InstrumentsDb::GetDb() {      String InstrumentsDb::GetDefaultDBLocation() {
127          if ( db != NULL) return db;          #ifdef WIN32
128            char* userprofile = getenv("USERPROFILE");
129            if (userprofile) {
130                String s = userprofile;
131                s += "\\.linuxsampler\\instruments.db";
132                return s;
133            } else {
134                // in case USERPROFILE is not set (which should not occur)
135                return "instruments.db";
136            }
137            #else // POSIX ...
138            String s = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;
139            # if defined(__APPLE__)
140            if (s.find("~") == 0)
141                s.replace(0, 1, getenv("HOME"));
142            # endif
143            return s;
144            #endif
145        }
146    
147          if (DbFile.empty()) {      void InstrumentsDb::EnsureDBFileExists() {
148                      #ifndef WIN32          if (DbFile.empty())
149                      DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;              DbFile = GetDefaultDBLocation();
                         #else  
                         char *userprofile = getenv("USERPROFILE");  
                         if(userprofile) {  
                             String DbPath = userprofile;  
                                 DbPath += "\\.linuxsampler";  
                             DbFile = DbPath + "\\instruments.db";  
                                 File InstrumentsDbFile(DbFile);  
                                 // if no DB exists create the subdir and then the DB  
                                 if( !InstrumentsDbFile.Exist() ) {  
                                     _mkdir( DbPath.c_str() );  
                                         // formats the DB, which creates a new instruments.db file  
                                         Format();  
                                 }  
                     }  
                         else {  
                             // in case USERPROFILE is not set (which should not occur)  
                             DbFile = "instruments.db";  
                         }  
                         #endif  
             }  
150                  #if defined(__APPLE__)  /* 20071224 Toshi Nagata  */                  #if defined(__APPLE__)  /* 20071224 Toshi Nagata  */
151                  if (DbFile.find("~") == 0)                  if (DbFile.find("~") == 0)
152                          DbFile.replace(0, 1, getenv("HOME"));                          DbFile.replace(0, 1, getenv("HOME"));
153                  #endif                  #endif
154            Path DbPath(DbFile);
155            String DbDir = DbPath.stripLastName();
156            // create directory if it does not exist yet
157            if (!DbPath.nodes().empty()) {
158                File d(DbDir);
159                if (!d.Exist()) {
160                    #ifdef WIN32
161                    if (_mkdir(DbDir.c_str()))
162                        throw Exception("Could not create instruments DB directory '" + DbDir + "'");
163                    #else
164                    if (mkdir(DbDir.c_str(), S_IRWXU))
165                        throw Exception("Could not create instruments DB directory '" + DbDir + "'");
166                    #endif
167                }
168            }
169            // create database file if it does not exist yet
170            File f(DbFile);
171            if (!f.Exist()) {
172                // formats the DB, which creates a new instruments.db file
173                Format();
174            }
175        }
176    
177        sqlite3* InstrumentsDb::GetDb() {
178            if ( db != NULL) return db;
179    
180            if (DbFile.empty())
181                DbFile = GetDefaultDBLocation();
182    
183            {
184                // first check if the instruments DB's directory exists, if not give up
185                Path path(DbFile);
186                String sDir = path.stripLastName();
187                File d(sDir);
188                if (!d.Exist())
189                    throw Exception("Instruments DB directory '" + sDir + "' does not exist!");
190    
191                // just to give the user a notice about the DB file being created in case it does not exist yet
192                File f(DbFile);
193                if (!f.Exist())
194                    dmsg(0,("Instruments DB file '%s' does not exist yet. Trying to create it now.\n", DbFile.c_str()));
195            }
196    
197            dmsg(0,("Opening instruments DB at '%s'\n", DbFile.c_str()));
198          int rc = sqlite3_open(DbFile.c_str(), &db);          int rc = sqlite3_open(DbFile.c_str(), &db);
199          if (rc) {          if (rc) {
200              sqlite3_close(db);              sqlite3_close(db);
# Line 464  namespace LinuxSampler { Line 509  namespace LinuxSampler {
509    
510      bool InstrumentsDb::DirectoryExist(String Dir) {      bool InstrumentsDb::DirectoryExist(String Dir) {
511          dmsg(2,("InstrumentsDb: DirectoryExist(Dir=%s)\n", Dir.c_str()));          dmsg(2,("InstrumentsDb: DirectoryExist(Dir=%s)\n", Dir.c_str()));
512          bool b;          {
513                LockGuard lock(DbInstrumentsMutex);
514          DbInstrumentsMutex.Lock();              return GetDirectoryId(Dir) != -1;
         try { b = GetDirectoryId(Dir) != -1; }  
         catch (Exception e) {  
             DbInstrumentsMutex.Unlock();  
             throw e;  
515          }          }
         DbInstrumentsMutex.Unlock();  
   
         return b;  
516      }      }
517    
518      DbDirectory InstrumentsDb::GetDirectoryInfo(String Dir) {      DbDirectory InstrumentsDb::GetDirectoryInfo(String Dir) {
# Line 714  namespace LinuxSampler { Line 752  namespace LinuxSampler {
752          dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,insDir=%d,FilePath=%s,Index=%d)\n", DbDir.c_str(), insDir, FilePath.c_str(), Index));          dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,insDir=%d,FilePath=%s,Index=%d)\n", DbDir.c_str(), insDir, FilePath.c_str(), Index));
753          if (DbDir.empty() || FilePath.empty()) return;          if (DbDir.empty() || FilePath.empty()) return;
754                    
755          DbInstrumentsMutex.Lock();          {
756          try {              LockGuard lock(DbInstrumentsMutex);
757    
758              int dirId = GetDirectoryId(DbDir);              int dirId = GetDirectoryId(DbDir);
759              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir));              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir));
760    
# Line 734  namespace LinuxSampler { Line 773  namespace LinuxSampler {
773    
774              String dir = insDir ? PrepareSubdirectory(DbDir, FilePath) : DbDir;              String dir = insDir ? PrepareSubdirectory(DbDir, FilePath) : DbDir;
775              AddInstrumentsFromFile(dir, FilePath, Index, pProgress);              AddInstrumentsFromFile(dir, FilePath, Index, pProgress);
         } catch (Exception e) {  
             DbInstrumentsMutex.Unlock();  
             throw e;  
776          }          }
   
         DbInstrumentsMutex.Unlock();  
777      }      }
778    
779      void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, bool insDir, ScanProgress* pProgress) {      void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, bool insDir, ScanProgress* pProgress) {
780          dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(DbDir=%s,FsDir=%s,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), insDir));          dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(DbDir=%s,FsDir=%s,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), insDir));
781          if (DbDir.empty() || FsDir.empty()) return;          if (DbDir.empty() || FsDir.empty()) return;
782                    
783          DbInstrumentsMutex.Lock();          {
784          try {              LockGuard lock(DbInstrumentsMutex);
785    
786              int dirId = GetDirectoryId(DbDir);              int dirId = GetDirectoryId(DbDir);
787              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
788    
# Line 774  namespace LinuxSampler { Line 809  namespace LinuxSampler {
809                  }                  }
810              } catch(Exception e) {              } catch(Exception e) {
811                  e.PrintMessage();                  e.PrintMessage();
                 DbInstrumentsMutex.Unlock();  
                 return;  
812              }              }
         } catch (Exception e) {  
             DbInstrumentsMutex.Unlock();  
             throw e;  
813          }          }
   
         DbInstrumentsMutex.Unlock();  
814      }      }
815    
816      void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, bool insDir, ScanProgress* pProgress) {      void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, bool insDir, ScanProgress* pProgress) {
# Line 1163  namespace LinuxSampler { Line 1191  namespace LinuxSampler {
1191          FireInstrumentInfoChanged(Instr);          FireInstrumentInfoChanged(Instr);
1192      }      }
1193    
1194      void InstrumentsDb::AddInstrumentsFromFile(String DbDir, String File, int Index, ScanProgress* pProgress) {      void InstrumentsDb::AddInstrumentsFromFile(String DbDir, String file, int Index, ScanProgress* pProgress) {
1195          dmsg(2,("InstrumentsDb: AddInstrumentsFromFile(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), File.c_str(), Index));          dmsg(2,("InstrumentsDb: AddInstrumentsFromFile(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), file.c_str(), Index));
1196            
1197          if(File.length() < 4) return;          if (!InstrumentFileInfo::isSupportedFile(file)) return;
1198            
1199          try {          try {
1200              if(!strcasecmp(".gig", File.substr(File.length() - 4).c_str())) {              if (pProgress != NULL) {
1201                  if (pProgress != NULL) {                  pProgress->SetStatus(0);
1202                      pProgress->SetStatus(0);                  pProgress->CurrentFile = file;
1203                      pProgress->CurrentFile = File;              }
                 }  
1204    
1205                  AddGigInstruments(DbDir, File, Index, pProgress);              int dirId = GetDirectoryId(DbDir);
1206                if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
1207    
1208                  if (pProgress != NULL) {              File f = File(file);
1209                      pProgress->SetScannedFileCount(pProgress->GetScannedFileCount() + 1);              if (!f.Exist()) {
1210                  }                  std::stringstream ss;
1211                    ss << "Fail to stat `" << file << "`: " << f.GetErrorMsg();
1212                    throw Exception(ss.str());
1213                }
1214    
1215                if (!f.IsFile()) {
1216                    std::stringstream ss;
1217                    ss << "`" << file << "` is not a regular file";
1218                    throw Exception(ss.str());
1219                }
1220    
1221                AddInstrumentsFromFilePriv(DbDir, dirId, file, f, Index, pProgress);
1222    
1223                if (pProgress != NULL) {
1224                    pProgress->SetScannedFileCount(pProgress->GetScannedFileCount() + 1);
1225              }              }
1226          } catch(Exception e) {          } catch(Exception e) {
1227              e.PrintMessage();              e.PrintMessage();
1228          }          }
1229      }      }
1230    
1231      void InstrumentsDb::AddGigInstruments(String DbDir, String FilePath, int Index, ScanProgress* pProgress) {      void InstrumentsDb::AddInstrumentsFromFilePriv(String DbDir, const int dirId, String FilePath, File file, int Index, ScanProgress* pProgress) {
1232          dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,FilePath=%s,Index=%d)\n", DbDir.c_str(), FilePath.c_str(), Index));          dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,FilePath=%s,Index=%d)\n", DbDir.c_str(), FilePath.c_str(), Index));
         int dirId = GetDirectoryId(DbDir);  
         if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));  
   
         File f = File(FilePath);  
         if (!f.Exist()) {  
             std::stringstream ss;  
             ss << "Fail to stat `" << FilePath << "`: " << f.GetErrorMsg();  
             throw Exception(ss.str());  
         }  
   
         if (!f.IsFile()) {  
             std::stringstream ss;  
             ss << "`" << FilePath << "` is not a regular file";  
             throw Exception(ss.str());  
         }  
1233    
1234          bool unlocked = false;          bool unlocked = false;
1235          RIFF::File* riff = NULL;          InstrumentFileInfo* fileInfo = NULL;
1236          gig::File* gig = NULL;          sqlite3_stmt* pStmt = NULL;
1237          try {          try {
1238              riff = new RIFF::File(FilePath);              fileInfo = InstrumentFileInfo::getFileInfoFor(FilePath);
1239              gig::File* gig = new gig::File(riff);              if (!fileInfo) return;
             gig->SetAutoLoad(false); // avoid time consuming samples scanning  
1240    
1241              std::stringstream sql;              std::stringstream sql;
1242              sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,";              sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,";
1243              sql << "instr_nr,format_family,format_version,instr_size,";              sql << "instr_nr,format_family,format_version,instr_size,";
1244              sql << "description,is_drum,product,artists,keywords) VALUES (";              sql << "description,is_drum,product,artists,keywords) VALUES (";
1245              sql << dirId << ",?,?,?,'GIG',?," << f.GetSize() << ",?,?,?,?,?)";              sql << dirId << ",?,?,?,?,?," << file.GetSize() << ",?,?,?,?,?)";
1246    
1247              sqlite3_stmt* pStmt = NULL;              // instr_name 1
1248                // instr_file 2
1249                // instr_nr 3
1250                // format_family 4
1251                // format_version 5
1252                // description 6
1253                // is_drum 7
1254                // product 8
1255                // artists 9
1256                // keywords 10
1257    
1258              int res = sqlite3_prepare(GetDb(), sql.str().c_str(), -1, &pStmt, NULL);              int res = sqlite3_prepare(GetDb(), sql.str().c_str(), -1, &pStmt, NULL);
1259              if (res != SQLITE_OK) {              if (res != SQLITE_OK) {
1260                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1261              }              }
1262    
1263              String s = FilePath;              BindTextParam(pStmt, 2, toEscapedFsPath(FilePath));
1264              s = toEscapedFsPath(s);              BindTextParam(pStmt, 4, fileInfo->formatName());
1265              BindTextParam(pStmt, 2, s);              BindTextParam(pStmt, 5, fileInfo->formatVersion());
1266              String ver = "";  
1267              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);              int instrIndex = (Index == -1) ? 0 : Index;
1268              BindTextParam(pStmt, 4, ver);  
1269                // Assume that it's locked and should be unlocked at this point
1270              if (Index == -1) {              // to be able to use the database from another threads
1271                  int instrIndex = 0;              if (!InTransaction) {
1272                  // Assume that it's locked and should be unlocked at this point                  DbInstrumentsMutex.Unlock();
1273                  // to be able to use the database from another threads                  unlocked = true;
1274                  if (!InTransaction) {              } else {
1275                      DbInstrumentsMutex.Unlock();                  std::cerr << "Shouldn't be in transaction when adding instruments." << std::endl;
1276                      unlocked = true;              }
                 } else {  
                     std::cerr << "Shouldn't be in transaction when adding instruments." << std::endl;  
                 }  
1277    
1278                  if (pProgress != NULL) gig->GetInstrument(0, &(pProgress->GigFileProgress)); // TODO: this workaround should be fixed              optional<InstrumentInfo> info = fileInfo->getInstrumentInfo(0, pProgress);
1279                  gig::Instrument* pInstrument = gig->GetFirstInstrument();              if (!InTransaction) DbInstrumentsMutex.Lock();
1280                while (info) {
1281                    String instrumentName = info->instrumentName;
1282                    if (instrumentName.empty())
1283                        instrumentName = Path::getBaseName(FilePath);
1284                    instrumentName = GetUniqueName(dirId, instrumentName);
1285    
1286                    BindTextParam(pStmt, 8, info->product);
1287                    BindTextParam(pStmt, 9, info->artists);
1288                    BindTextParam(pStmt, 10, info->keywords);
1289    
1290                    std::stringstream sql2;
1291                    sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";
1292                    sql2 << "instr_nr=" << instrIndex;
1293                    String s = toEscapedFsPath(FilePath);
1294                    if (ExecSqlInt(sql2.str(), s) > 0) goto next;
1295    
1296                  if (!InTransaction) DbInstrumentsMutex.Lock();                  BindTextParam(pStmt, 1, instrumentName);
1297                  while (pInstrument) {                  BindIntParam(pStmt, 3, instrIndex);
                     BindTextParam(pStmt, 7, gig->pInfo->Product);  
                     BindTextParam(pStmt, 8, gig->pInfo->Artists);  
                     BindTextParam(pStmt, 9, gig->pInfo->Keywords);  
                     AddGigInstrument(pStmt, DbDir, dirId, FilePath, pInstrument, instrIndex);  
1298    
1299                      instrIndex++;                  BindTextParam(pStmt, 6, info->comments);
1300                      pInstrument = gig->GetNextInstrument();                  BindIntParam(pStmt, 7, info->isDrum);
1301                  }  
1302              } else {                  res = sqlite3_step(pStmt);
1303                  gig::Instrument* pInstrument;                  if (res != SQLITE_DONE) {
1304                  if (pProgress == NULL) pInstrument = gig->GetInstrument(Index);                      throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
                 else pInstrument = gig->GetInstrument(Index, &(pProgress->GigFileProgress));  
                 if (pInstrument != NULL) {  
                     BindTextParam(pStmt, 7, gig->pInfo->Product);  
                     BindTextParam(pStmt, 8, gig->pInfo->Artists);  
                     BindTextParam(pStmt, 9, gig->pInfo->Keywords);  
                     AddGigInstrument(pStmt, DbDir, dirId, FilePath, pInstrument, Index);  
1305                  }                  }
1306              }                  res = sqlite3_reset(pStmt);
1307                    FireInstrumentCountChanged(DbDir);
1308    
1309              sqlite3_finalize(pStmt);              next:
1310              delete gig;                  if (Index != -1) break;
1311              delete riff;  
1312          } catch (RIFF::Exception e) {                  instrIndex++;
1313              if (gig != NULL) delete gig;                  info = fileInfo->getInstrumentInfo(instrIndex, pProgress);
1314              if (riff != NULL) delete riff;              }
1315            } catch (Exception e) {
1316                if (pStmt) sqlite3_finalize(pStmt);
1317                if (fileInfo) delete fileInfo;
1318              if (unlocked) DbInstrumentsMutex.Lock();              if (unlocked) DbInstrumentsMutex.Lock();
1319              std::stringstream ss;              std::stringstream ss;
1320              ss << "Failed to scan `" << FilePath << "`: " << e.Message;              ss << "Failed to scan `" << FilePath << "`: " << e.Message();
               
1321              throw Exception(ss.str());              throw Exception(ss.str());
         } catch (Exception e) {  
             if (gig != NULL) delete gig;  
             if (riff != NULL) delete riff;  
             if (unlocked) DbInstrumentsMutex.Lock();  
             throw e;  
1322          } catch (...) {          } catch (...) {
1323              if (gig != NULL) delete gig;              if (pStmt) sqlite3_finalize(pStmt);
1324              if (riff != NULL) delete riff;              if (fileInfo) delete fileInfo;
1325              if (unlocked) DbInstrumentsMutex.Lock();              if (unlocked) DbInstrumentsMutex.Lock();
1326              throw Exception("Failed to scan `" + FilePath + "`");              throw Exception("Failed to scan `" + FilePath + "`");
1327          }          }
1328      }          if (pStmt) sqlite3_finalize(pStmt);
1329            if (fileInfo) delete fileInfo;
1330      void InstrumentsDb::AddGigInstrument(sqlite3_stmt* pStmt, String DbDir, int DirId, String File, gig::Instrument* pInstrument, int Index) {          if (unlocked) DbInstrumentsMutex.Lock();
         dmsg(2,("InstrumentsDb: AddGigInstrument(DbDir=%s,DirId=%d,File=%s,Index=%d)\n", DbDir.c_str(), DirId, File.c_str(), Index));  
         String name = pInstrument->pInfo->Name;  
         if (name == "") return;  
         name = GetUniqueName(DirId, name);  
           
         std::stringstream sql2;  
         sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";  
         sql2 << "instr_nr=" << Index;  
         String s = toEscapedFsPath(File);  
         if (ExecSqlInt(sql2.str(), s) > 0) return;  
   
         BindTextParam(pStmt, 1, name);  
         BindIntParam(pStmt, 3, Index);  
   
         BindTextParam(pStmt, 5, pInstrument->pInfo->Comments);  
         BindIntParam(pStmt, 6, pInstrument->IsDrum);  
   
         if (!pInstrument->pInfo->Product.empty()) {  
             BindTextParam(pStmt, 7, pInstrument->pInfo->Product);  
         }  
         if (!pInstrument->pInfo->Artists.empty()) {  
             BindTextParam(pStmt, 8, pInstrument->pInfo->Artists);  
         }  
   
         if (!pInstrument->pInfo->Keywords.empty()) {  
             BindTextParam(pStmt, 9, pInstrument->pInfo->Keywords);  
         }  
   
         int res = sqlite3_step(pStmt);  
         if(res != SQLITE_DONE) {  
             sqlite3_finalize(pStmt);  
             throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));  
         }  
   
         res = sqlite3_reset(pStmt);  
         FireInstrumentCountChanged(DbDir);  
1331      }      }
1332    
1333      void InstrumentsDb::DirectoryTreeWalk(String AbstractPath, DirectoryHandler* pHandler) {      void InstrumentsDb::DirectoryTreeWalk(String AbstractPath, DirectoryHandler* pHandler) {
# Line 1466  namespace LinuxSampler { Line 1465  namespace LinuxSampler {
1465          }          }
1466          InTransaction = false;          InTransaction = false;
1467                    
1468          if(db == NULL) {          if (db == NULL) {
1469              DbInstrumentsMutex.Unlock();              DbInstrumentsMutex.Unlock();
1470              return;              return;
1471          }          }
# Line 1670  namespace LinuxSampler { Line 1669  namespace LinuxSampler {
1669    
1670      void InstrumentsDb::BindTextParam(sqlite3_stmt* pStmt, int Index, String Text) {      void InstrumentsDb::BindTextParam(sqlite3_stmt* pStmt, int Index, String Text) {
1671          if (pStmt == NULL) return;          if (pStmt == NULL) return;
1672          int res = sqlite3_bind_text(pStmt, Index, Text.c_str(), -1, SQLITE_STATIC);          int res = sqlite3_bind_text(pStmt, Index, Text.c_str(), -1, SQLITE_TRANSIENT);
1673          if (res != SQLITE_OK) {          if (res != SQLITE_OK) {
1674              sqlite3_finalize(pStmt);              sqlite3_finalize(pStmt);
1675              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
# Line 1741  namespace LinuxSampler { Line 1740  namespace LinuxSampler {
1740      }      }
1741    
1742      void InstrumentsDb::Format() {      void InstrumentsDb::Format() {
1743          DbInstrumentsMutex.Lock();          {
1744          if (db != NULL) {              LockGuard lock(DbInstrumentsMutex);
             sqlite3_close(db);  
             db = NULL;  
         }  
1745    
1746          if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;              if (db != NULL) {
1747          String bkp = DbFile + ".bkp";                  sqlite3_close(db);
1748          remove(bkp.c_str());                  db = NULL;
1749          if (rename(DbFile.c_str(), bkp.c_str()) && errno != ENOENT) {              }
1750              DbInstrumentsMutex.Unlock();  
1751              throw Exception(String("Failed to backup database: ") + strerror(errno));              if (DbFile.empty()) DbFile = GetDefaultDBLocation();
1752          }              String bkp = DbFile + ".bkp";
1753                remove(bkp.c_str());
1754                if (rename(DbFile.c_str(), bkp.c_str()) && errno != ENOENT) {
1755                    throw Exception(String("Failed to backup database: ") + strerror(errno));
1756                }
1757                    
1758          String f = DbFile;              String f = DbFile;
1759          DbFile = "";              DbFile = "";
1760          try { CreateInstrumentsDb(f); }              CreateInstrumentsDb(f);
         catch(Exception e) {  
             DbInstrumentsMutex.Unlock();  
             throw e;  
1761          }          }
         DbInstrumentsMutex.Unlock();  
           
1762          FireDirectoryCountChanged("/");          FireDirectoryCountChanged("/");
1763          FireInstrumentCountChanged("/");          FireInstrumentCountChanged("/");
1764      }      }

Legend:
Removed from v.1944  
changed lines
  Added in v.3092

  ViewVC Help
Powered by ViewVC