NepomukDaemons
repository.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "repository.h"
00016 #include "nepomukstorage-config.h"
00017 #include "modelcopyjob.h"
00018
00019 #ifdef HAVE_CLUCENE
00020 #include "cluceneanalyzer.h"
00021 #endif
00022
00023 #include <Soprano/Backend>
00024 #include <Soprano/Global>
00025 #include <Soprano/Version>
00026 #include <Soprano/StorageModel>
00027 #include <Soprano/Error/Error>
00028 #include <Soprano/Vocabulary/Xesam>
00029
00030 #ifdef HAVE_SOPRANO_INDEX
00031 #include <Soprano/Index/IndexFilterModel>
00032 #include <Soprano/Index/CLuceneIndex>
00033 #endif
00034
00035 #include <KStandardDirs>
00036 #include <KDebug>
00037 #include <KConfigGroup>
00038 #include <KSharedConfig>
00039 #include <KLocale>
00040
00041
00042 namespace {
00043 QString createStoragePath( const QString& repositoryId )
00044 {
00045 return KStandardDirs::locateLocal( "data", "nepomuk/repository/" + repositoryId + "/" );
00046 }
00047 }
00048
00049
00050 Nepomuk::Repository::Repository( const QString& name )
00051 : m_name( name ),
00052 m_state( CLOSED ),
00053 m_model( 0 ),
00054 m_analyzer( 0 ),
00055 m_index( 0 ),
00056 m_indexModel( 0 )
00057 {
00058 }
00059
00060
00061 Nepomuk::Repository::~Repository()
00062 {
00063 close();
00064 }
00065
00066
00067 void Nepomuk::Repository::close()
00068 {
00069 if ( m_state == OPEN ) {
00070 #ifdef HAVE_SOPRANO_INDEX
00071 delete m_indexModel;
00072 delete m_index;
00073 m_indexModel = 0;
00074 m_index = 0;
00075 #ifdef HAVE_CLUCENE
00076 delete m_analyzer;
00077 m_analyzer = 0;
00078 #endif
00079 #endif
00080 delete m_model;
00081 m_model = 0;
00082
00083 m_state = CLOSED;
00084 }
00085 }
00086
00087
00088 void Nepomuk::Repository::open()
00089 {
00090 Q_ASSERT( m_state == CLOSED );
00091
00092 m_state = OPENING;
00093
00094
00095
00096 const Soprano::Backend* backend = activeSopranoBackend();
00097 if ( !backend ) {
00098 m_state = CLOSED;
00099 emit opened( this, false );
00100 return;
00101 }
00102
00103
00104
00105 KConfigGroup repoConfig = KSharedConfig::openConfig( "nepomukserverrc" )->group( name() + " Settings" );
00106 QString oldBackendName = repoConfig.readEntry( "Used Soprano Backend", backend->pluginName() );
00107 QString oldBasePath = repoConfig.readPathEntry( "Storage Dir", QString() );
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 m_basePath = oldBasePath.isEmpty() ? createStoragePath( name() ) : oldBasePath;
00121 QString indexPath = m_basePath + "index";
00122 QString storagePath = m_basePath + "data/" + backend->pluginName();
00123
00124 KStandardDirs::makeDir( indexPath );
00125 KStandardDirs::makeDir( storagePath );
00126
00127 kDebug(300002) << "opening repository '" << name() << "' at '" << m_basePath << "'";
00128
00129
00130
00131
00132 m_model = backend->createModel( QList<Soprano::BackendSetting>() << Soprano::BackendSetting( Soprano::BackendOptionStorageDir, storagePath ) );
00133 if ( !m_model ) {
00134 kDebug(300002) << "Unable to create model for repository" << name();
00135 m_state = CLOSED;
00136 emit opened( this, false );
00137 return;
00138 }
00139
00140 kDebug(300002) << "Successfully created new model for repository" << name();
00141
00142 #if defined(HAVE_SOPRANO_INDEX) && defined(HAVE_CLUCENE)
00143 m_analyzer = new CLuceneAnalyzer();
00144 m_index = new Soprano::Index::CLuceneIndex( m_analyzer );
00145
00146 if ( m_index->open( indexPath, true ) ) {
00147 kDebug(300002) << "Successfully created new index for repository" << name();
00148 m_indexModel = new Soprano::Index::IndexFilterModel( m_index, m_model );
00149
00150
00151 m_indexModel->setTransactionCacheSize( 100 );
00152
00153 #if SOPRANO_IS_VERSION(2,0,99)
00154
00155
00156 m_indexModel->addIndexOnlyPredicate( Soprano::Vocabulary::Xesam::asText() );
00157 #endif
00158
00159 setParentModel( m_indexModel );
00160 }
00161 else {
00162 kDebug(300002) << "Unable to open CLucene index for repo '" << name() << "': " << m_index->lastError();
00163 delete m_index;
00164 delete m_model;
00165 m_index = 0;
00166 m_model = 0;
00167
00168 m_state = CLOSED;
00169 emit opened( this, false );
00170 return;
00171 }
00172 #else
00173 setParentModel( m_model );
00174 #endif
00175
00176
00177
00178 bool convertingData = false;
00179
00180
00181
00182
00183 if ( oldBackendName != backend->pluginName() ||
00184 oldBasePath.isEmpty() ) {
00185
00186 kDebug() << "Previous backend:" << oldBackendName << "- new backend:" << backend->pluginName();
00187 kDebug() << "Old path:" << oldBasePath << "- new path:" << m_basePath;
00188
00189 if ( oldBasePath.isEmpty() ) {
00190
00191
00192 m_oldStoragePath = createStoragePath( name() );
00193 }
00194 else {
00195 m_oldStoragePath = m_basePath + "data/" + oldBackendName;
00196 }
00197
00198
00199 Soprano::Model* oldModel = 0;
00200 m_oldStorageBackend = Soprano::discoverBackendByName( oldBackendName );
00201 if ( m_oldStorageBackend ) {
00202
00203 oldModel = m_oldStorageBackend->createModel( QList<Soprano::BackendSetting>() << Soprano::BackendSetting( Soprano::BackendOptionStorageDir, m_oldStoragePath ) );
00204 }
00205
00206 if ( oldModel ) {
00207 if ( !oldModel->isEmpty() ) {
00208 kDebug() << "Starting model conversion";
00209
00210 convertingData = true;
00211
00212 ModelCopyJob* copyJob = new ModelCopyJob( oldModel, m_model, this );
00213 connect( copyJob, SIGNAL( result( KJob* ) ), this, SLOT( copyFinished( KJob* ) ) );
00214 copyJob->start();
00215 }
00216 else {
00217 m_state = OPEN;
00218 emit opened( this, true );
00219 }
00220 }
00221 else {
00222
00223 kDebug( 300002 ) << "Unable to convert old model.";
00224 m_state = OPEN;
00225 emit opened( this, true );
00226 }
00227 }
00228 else {
00229 kDebug() << "no need to convert" << name();
00230 m_state = OPEN;
00231 emit opened( this, true );
00232 }
00233
00234
00235
00236
00237
00238
00239 if ( !convertingData ) {
00240 repoConfig.writeEntry( "Used Soprano Backend", backend->pluginName() );
00241 repoConfig.writePathEntry( "Storage Dir", m_basePath );
00242 repoConfig.sync();
00243 }
00244 }
00245
00246
00247 void Nepomuk::Repository::copyFinished( KJob* job )
00248 {
00249 if ( job->error() ) {
00250
00251 kDebug( 300002 ) << "Converting old model failed.";
00252 }
00253 else {
00254 kDebug() << "Successfully converted model data for repo" << name();
00255
00256
00257 ModelCopyJob* copyJob = qobject_cast<ModelCopyJob*>( job );
00258 delete copyJob->source();
00259
00260
00261 m_oldStorageBackend->deleteModelData( QList<Soprano::BackendSetting>() << Soprano::BackendSetting( Soprano::BackendOptionStorageDir, m_oldStoragePath ) );
00262
00263
00264 KConfigGroup repoConfig = KSharedConfig::openConfig( "nepomukserverrc" )->group( name() + " Settings" );
00265 repoConfig.writeEntry( "Used Soprano Backend", activeSopranoBackend()->pluginName() );
00266 repoConfig.writePathEntry( "Storage Dir", m_basePath );
00267 repoConfig.sync();
00268 }
00269
00270
00271 m_state = OPEN;
00272 emit opened( this, true );
00273 }
00274
00275
00276 const Soprano::Backend* Nepomuk::Repository::activeSopranoBackend()
00277 {
00278 QString backendName = KSharedConfig::openConfig( "nepomukserverrc" )->group( "Basic Settings" ).readEntry( "Soprano Backend", "sesame2" );
00279 const Soprano::Backend* backend = ::Soprano::discoverBackendByName( backendName );
00280 if ( !backend ) {
00281 kDebug(300002) << "(Nepomuk::Core::Core) could not find backend" << backendName << ". Falling back to default.";
00282 backend = ::Soprano::usedBackend();
00283 }
00284 if ( !backend ) {
00285 kDebug(300002) << "(Nepomuk::Core::Core) could not find a backend.";
00286 }
00287 return backend;
00288 }
00289
00290 #include "repository.moc"