/[svn]/linuxsampler/trunk/src/db/InstrumentsDbUtilities.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/db/InstrumentsDbUtilities.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 1943 by persson, Tue Jul 14 18:25:11 2009 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2007 Grigor Iliev                                       *   *   Copyright (C) 2007 - 2009 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 "InstrumentsDbUtilities.h"  #include "InstrumentsDbUtilities.h"
22    
23  #if HAVE_SQLITE3  #include "../common/File.h"
24    #include "../common/global_private.h"
25    
26  #include <dirent.h>  #include <algorithm>
27  #include <errno.h>  #include <errno.h>
 #include <ftw.h>  
28    
29  #include "../common/Exception.h"  #include "../common/Exception.h"
30  #include "InstrumentsDb.h"  #include "InstrumentsDb.h"
# Line 153  namespace LinuxSampler { Line 153  namespace LinuxSampler {
153          if (Pattern.length() == 0) return;          if (Pattern.length() == 0) return;
154    
155          if (IsRegex(Pattern)) {          if (IsRegex(Pattern)) {
156    #ifndef WIN32
157              Sql << " AND " << Col << " regexp ?";              Sql << " AND " << Col << " regexp ?";
158    #else
159                for (int i = 0; i < Pattern.length(); i++) {
160                    if (Pattern.at(i) == '?') Pattern.at(i) = '_';
161                    else if (Pattern.at(i) == '*') Pattern.at(i) = '%';
162                }
163                Sql << " AND " << Col << " LIKE ?";
164    #endif
165              Params.push_back(Pattern);              Params.push_back(Pattern);
166              return;              return;
167          }          }
# Line 254  namespace LinuxSampler { Line 262  namespace LinuxSampler {
262          if(Path.compare("/") != 0) s += "/";          if(Path.compare("/") != 0) s += "/";
263          int res = sqlite3_step(pStmt);          int res = sqlite3_step(pStmt);
264          while(res == SQLITE_ROW) {          while(res == SQLITE_ROW) {
265              pDirectories->push_back(s + ToString(sqlite3_column_text(pStmt, 0)));              pDirectories->push_back(s + idb->toAbstractName(ToString(sqlite3_column_text(pStmt, 0))));
266              res = sqlite3_step(pStmt);              res = sqlite3_step(pStmt);
267          }          }
268                    
# Line 339  namespace LinuxSampler { Line 347  namespace LinuxSampler {
347          if(Path.compare("/") != 0) s += "/";          if(Path.compare("/") != 0) s += "/";
348          int res = sqlite3_step(pStmt);          int res = sqlite3_step(pStmt);
349          while(res == SQLITE_ROW) {          while(res == SQLITE_ROW) {
350              pInstruments->push_back(s + ToString(sqlite3_column_text(pStmt, 0)));              pInstruments->push_back(s + idb->toAbstractName(ToString(sqlite3_column_text(pStmt, 0))));
351              res = sqlite3_step(pStmt);              res = sqlite3_step(pStmt);
352          }          }
353                    
# Line 391  namespace LinuxSampler { Line 399  namespace LinuxSampler {
399          }          }
400    
401          int dstDirId = db->GetDirectoryId(dir);          int dstDirId = db->GetDirectoryId(dir);
402          if(dstDirId == -1) throw Exception("Unkown DB directory: " + dir);          if(dstDirId == -1) {
403                throw Exception("Unkown DB directory: " + InstrumentsDb::toEscapedPath(dir));
404            }
405          IntListPtr ids = db->GetInstrumentIDs(DirId);          IntListPtr ids = db->GetInstrumentIDs(DirId);
406          for (int i = 0; i < ids->size(); i++) {          for (int i = 0; i < ids->size(); i++) {
407              String name = db->GetInstrumentName(ids->at(i));              String name = db->GetInstrumentName(ids->at(i));
# Line 462  namespace LinuxSampler { Line 472  namespace LinuxSampler {
472          sp->SetStatus((int)(pProgress->factor * 100));          sp->SetStatus((int)(pProgress->factor * 100));
473      }      }
474    
475      AddInstrumentsJob::AddInstrumentsJob(int JobId, ScanMode Mode, String DbDir, String FsDir) {      AddInstrumentsJob::AddInstrumentsJob(int JobId, ScanMode Mode, String DbDir, String FsDir, bool insDir) {
476          this->JobId = JobId;          this->JobId = JobId;
477          Progress.JobId = JobId;          Progress.JobId = JobId;
478          this->Mode = Mode;          this->Mode = Mode;
479          this->DbDir = DbDir;          this->DbDir = DbDir;
480          this->FsDir = FsDir;          this->FsDir = FsDir;
481                    this->insDir = insDir;
482      }      }
483    
484      void AddInstrumentsJob::Run() {      void AddInstrumentsJob::Run() {
# Line 477  namespace LinuxSampler { Line 488  namespace LinuxSampler {
488              switch (Mode) {              switch (Mode) {
489                  case NON_RECURSIVE:                  case NON_RECURSIVE:
490                      Progress.SetTotalFileCount(GetFileCount());                      Progress.SetTotalFileCount(GetFileCount());
491                      db->AddInstrumentsNonrecursive(DbDir, FsDir, &Progress);                      db->AddInstrumentsNonrecursive(DbDir, FsDir, insDir, &Progress);
492                      break;                      break;
493                  case RECURSIVE:                  case RECURSIVE:
494                      db->AddInstrumentsRecursive(DbDir, FsDir, false, &Progress);                      db->AddInstrumentsRecursive(DbDir, FsDir, false, insDir, &Progress);
495                      break;                      break;
496                  case FLAT:                  case FLAT:
497                      db->AddInstrumentsRecursive(DbDir, FsDir, true, &Progress);                      db->AddInstrumentsRecursive(DbDir, FsDir, true, insDir, &Progress);
498                      break;                      break;
499                  default:                  default:
500                      throw Exception("Unknown scan mode");                      throw Exception("Unknown scan mode");
501              }              }
502    
503                // Just to be sure that the frontends will be notified about the job completion
504                if (Progress.GetTotalFileCount() != Progress.GetScannedFileCount()) {
505                    Progress.SetTotalFileCount(Progress.GetScannedFileCount());
506                }
507                if (Progress.GetStatus() != 100) Progress.SetStatus(100);
508          } catch(Exception e) {          } catch(Exception e) {
509              Progress.SetErrorStatus(-1);              Progress.SetErrorStatus(-1);
510              throw e;              throw e;
# Line 497  namespace LinuxSampler { Line 514  namespace LinuxSampler {
514      int AddInstrumentsJob::GetFileCount() {      int AddInstrumentsJob::GetFileCount() {
515          int count = 0;          int count = 0;
516    
517          DIR* pDir = opendir(FsDir.c_str());          try {
518          if (pDir == NULL) {              FileListPtr fileList = File::GetFiles(FsDir);
             std::stringstream ss;  
             ss << "The scanning of directory `" << FsDir << "` failed: ";  
             ss << strerror(errno);  
             std::cerr << ss.str();  
             return 0;  
         }  
519    
520          struct dirent* pEnt = readdir(pDir);              for (int i = 0; i < fileList->size(); i++) {
521          while (pEnt != NULL) {                  String s = fileList->at(i);
522              if (pEnt->d_type != DT_REG) {                  if (s.length() < 4) continue;
523                  pEnt = readdir(pDir);                  if(!strcasecmp(".gig", s.substr(s.length() - 4).c_str())) count++;
                 continue;  
524              }              }
525            } catch(Exception e) {
526              count++;              e.PrintMessage();
527              pEnt = readdir(pDir);              return 0;
         }  
           
         if (closedir(pDir)) {  
             std::stringstream ss;  
             ss << "Failed to close directory `" << FsDir << "`: ";  
             ss << strerror(errno);  
             std::cerr << ss.str();  
528          }          }
529                    
530          return count;          return count;
531      }      }
532    
533      AddInstrumentsFromFileJob::AddInstrumentsFromFileJob(int JobId, String DbDir, String FilePath, int Index) {      AddInstrumentsFromFileJob::AddInstrumentsFromFileJob(int JobId, String DbDir, String FilePath, int Index, bool insDir) {
534          this->JobId = JobId;          this->JobId = JobId;
535          Progress.JobId = JobId;          Progress.JobId = JobId;
536          Progress.SetTotalFileCount(1);          Progress.SetTotalFileCount(1);
# Line 535  namespace LinuxSampler { Line 538  namespace LinuxSampler {
538          this->DbDir = DbDir;          this->DbDir = DbDir;
539          this->FilePath = FilePath;          this->FilePath = FilePath;
540          this->Index = Index;          this->Index = Index;
541                    this->insDir = insDir;
542      }      }
543    
544      void AddInstrumentsFromFileJob::Run() {      void AddInstrumentsFromFileJob::Run() {
545          InstrumentsDb::GetInstrumentsDb()->AddInstruments(DbDir, FilePath, Index, &Progress);          try {
546      }              InstrumentsDb::GetInstrumentsDb()->AddInstruments(DbDir, insDir, FilePath, Index, &Progress);
547    
548                // Just to be sure that the frontends will be notified about the job completion
549                if (Progress.GetTotalFileCount() != Progress.GetScannedFileCount()) {
550                    Progress.SetTotalFileCount(Progress.GetScannedFileCount());
551                }
552                if (Progress.GetStatus() != 100) Progress.SetStatus(100);
553            } catch(Exception e) {
554                Progress.SetErrorStatus(-1);
555                throw e;
556            }
557        }
558    
     String DirectoryScanner::DbDir;  
     String DirectoryScanner::FsDir;  
     bool DirectoryScanner::Flat;  
     ScanProgress* DirectoryScanner::pProgress;  
559    
560      void DirectoryScanner::Scan(String DbDir, String FsDir, bool Flat, ScanProgress* pProgress) {      void DirectoryScanner::Scan(String DbDir, String FsDir, bool Flat, bool insDir, ScanProgress* pProgress) {
561          dmsg(2,("DirectoryScanner: Scan(DbDir=%s,FsDir=%s,Flat=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat));          dmsg(2,("DirectoryScanner: Scan(DbDir=%s,FsDir=%s,Flat=%d,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat, insDir));
562          if (DbDir.empty() || FsDir.empty()) throw Exception("Directory expected");          if (DbDir.empty() || FsDir.empty()) throw Exception("Directory expected");
563                    
564          struct stat statBuf;          this->DbDir = DbDir;
565          int res = stat(FsDir.c_str(), &statBuf);          this->FsDir = FsDir;
566          if (res) {          this->insDir = insDir;
             std::stringstream ss;  
             ss << "Fail to stat `" << FsDir << "`: " << strerror(errno);  
             throw Exception(ss.str());  
         }  
   
         if (!S_ISDIR(statBuf.st_mode)) {  
             throw Exception("Directory expected");  
         }  
           
         DirectoryScanner::DbDir = DbDir;  
         DirectoryScanner::FsDir = FsDir;  
567          if (DbDir.at(DbDir.length() - 1) != '/') {          if (DbDir.at(DbDir.length() - 1) != '/') {
568              DirectoryScanner::DbDir.append("/");              this->DbDir.append("/");
569          }          }
570          if (FsDir.at(FsDir.length() - 1) != '/') {          if (FsDir.at(FsDir.length() - 1) != File::DirSeparator) {
571              DirectoryScanner::FsDir.append("/");              this->FsDir.push_back(File::DirSeparator);
572          }          }
573          DirectoryScanner::Flat = Flat;          this->Flat = Flat;
574          DirectoryScanner::pProgress = pProgress;          this->pProgress = pProgress;
575                    
576          ftw(FsDir.c_str(), FtwCallback, 10);          File::WalkDirectoryTree(FsDir, this);
577      }      }
578    
579      int DirectoryScanner::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {      void DirectoryScanner::DirectoryEntry(std::string Path) {
580          dmsg(2,("DirectoryScanner: FtwCallback(fpath=%s)\n", fpath));          dmsg(2,("DirectoryScanner: DirectoryEntry(Path=%s)\n", Path.c_str()));
         if (typeflag != FTW_D) return 0;  
581    
582          String dir = DbDir;          String dir = DbDir;
583          if (!Flat) {          if (!Flat) {
584              String subdir = fpath;              String subdir = Path;
585              if(subdir.length() > FsDir.length()) {              if(subdir.length() > FsDir.length()) {
586                  subdir = subdir.substr(FsDir.length());                  subdir = subdir.substr(FsDir.length());
587    #ifdef WIN32
588                    replace(subdir.begin(), subdir.end(), '\\', '/');
589    #endif
590                  dir += subdir;                  dir += subdir;
591              }              }
592          }          }
593                    
594          InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();          InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
         if (!db->DirectoryExist(dir)) db->AddDirectory(dir);  
595    
596          db->AddInstrumentsNonrecursive(dir, String(fpath), pProgress);          if (HasInstrumentFiles(Path)) {
597                if (!db->DirectoryExist(dir)) db->AddDirectory(dir);
598          return 0;              db->AddInstrumentsNonrecursive(dir, Path, insDir, pProgress);
599            }
600      };      };
601    
602      int InstrumentFileCounter::FileCount;      bool DirectoryScanner::HasInstrumentFiles(String Dir) {
603            InstrumentFileCounter c;
604            return c.Count(Dir) > 0;
605        }
606    
607      int InstrumentFileCounter::Count(String FsDir) {      int InstrumentFileCounter::Count(String FsDir) {
608          dmsg(2,("InstrumentFileCounter: Count(FsDir=%s)\n", FsDir.c_str()));          dmsg(2,("InstrumentFileCounter: Count(FsDir=%s)\n", FsDir.c_str()));
609          if (FsDir.empty()) throw Exception("Directory expected");          if (FsDir.empty()) throw Exception("Directory expected");
610          FileCount = 0;          FileCount = 0;
611    
612          struct stat statBuf;          File::WalkDirectoryTree(FsDir, this);
         int res = stat(FsDir.c_str(), &statBuf);  
         if (res) {  
             std::stringstream ss;  
             ss << "Fail to stat `" << FsDir << "`: " << strerror(errno);  
             throw Exception(ss.str());  
         }  
   
         if (!S_ISDIR(statBuf.st_mode)) {  
             throw Exception("Directory expected");  
         }  
           
         ftw(FsDir.c_str(), FtwCallback, 10);  
613          return FileCount;          return FileCount;
614      }      }
615    
616      int InstrumentFileCounter::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) {      void InstrumentFileCounter::FileEntry(std::string Path) {
617          if (typeflag != FTW_F) return 0;          dmsg(2,("InstrumentFileCounter: FileEntry(Path=%s)\n", Path.c_str()));
618          String s = fpath;          if(Path.length() < 4) return;
619          if(s.length() < 4) return 0;          if(!strcasecmp(".gig", Path.substr(Path.length() - 4).c_str())) FileCount++;
         if(!strcasecmp(".gig", s.substr(s.length() - 4).c_str())) FileCount++;  
         return 0;  
620      };      };
621    
622  } // namespace LinuxSampler  } // namespace LinuxSampler
   
 #endif // HAVE_SQLITE3  

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

  ViewVC Help
Powered by ViewVC