00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 void DatabaseWizard::init()
00011 {
00012 #ifndef NDEBUG
00013 std::cerr << "Initialise" << std::endl;
00014 #endif
00015
00016
00017 databaseUserEdit->setText( getenv( "USER" ) );
00018
00019
00020 setNextEnabled( connectPage , false );
00021 setNextEnabled( createDatabasePage, false );
00022 setNextEnabled( createUserPage , false );
00023 setFinishEnabled( importRecipesPage, true );
00024
00025 const char *home = getenv( "HOME" );
00026 #ifndef NDEBUG
00027 std::cerr << "HOME = " << home << std::endl;
00028 #endif
00029 if ( home != NULL ) {
00030 socketEdit->setText( QString( home ) +
00031 "/.kde/share/apps/anymeal/db/mysql.sock" );
00032 };
00033 serverWidgetStack->raiseWidget( serverTypeCombo->currentItem() );
00034 }
00035
00036
00037 void DatabaseWizard::connectButtonEnable()
00038 {
00039 serverUser.reset();
00040 serverRoot.reset();
00041 daemon.reset();
00042
00043 connectButton->setEnabled
00044 ( !( serverTypeCombo->currentItem() == 0 ?
00045 serverEdit->text() :
00046 socketEdit->text() ).isEmpty() &&
00047 !rootUserEdit->text().isEmpty() &&
00048 ( !rootPassWordCheckBox->isChecked() ||
00049 !rootPassWordEdit->text().isEmpty() ) );
00050
00051 setNextEnabled( connectPage, false );
00052 createDatabaseEnable();
00053 }
00054
00055
00056 void DatabaseWizard::connectToServer()
00057 {
00058 try {
00059
00060 assert( serverTypeCombo->count() == 2 );
00061 assert( serverTypeCombo->text( 0 ) == i18n( "Network" ) );
00062 assert( serverTypeCombo->text( 1 ) == i18n( "Embedded" ) );
00063
00064 assert( !( serverTypeCombo->currentItem() == 0 ?
00065 serverEdit->text() :
00066 socketEdit->text() ).isEmpty() );
00067 assert( !rootUserEdit->text().isEmpty() );
00068 assert( !rootPassWordCheckBox->isChecked() ||
00069 !rootPassWordEdit->text().isEmpty() );
00070
00071 switch ( serverTypeCombo->currentItem() ) {
00072 case 0: {
00073 DisplayWaitCursor w;
00074 serverRoot = MySQLServerPtr
00075 ( new MySQLNetwork( rootUserEdit->text(),
00076 rootPassWordCheckBox->isChecked() ?
00077 (const char *)rootPassWordEdit->text() : "",
00078 serverEdit->text(), MYSQL_PORT ) );
00079 break;}
00080 case 1: {
00081 daemon = MySQLDaemonPtr( new MySQLDaemon
00082 ( createDatabase( folderEdit->text() ),
00083 socketEdit->text() ) );
00084 DisplayWaitCursor w;
00085 serverRoot = MySQLServerPtr
00086 ( new MySQLSocket( rootUserEdit->text(),
00087 rootPassWordCheckBox->isChecked() ?
00088 (const char *)rootPassWordEdit->text() : "",
00089 socketEdit->text(), daemon ) );
00090 break;}
00091 default:
00092 assert( false );
00093 };
00094
00095
00096 connectButton->setEnabled( false );
00097
00098 setNextEnabled( connectPage, true );
00099
00100 } catch ( std::exception &e ) {
00101
00102 #ifndef NDEBUG
00103 std::cerr << "Error connecting." << std::endl;
00104 #endif
00105 KMessageBox::error( this, e.what() );
00106
00107 };
00108 }
00109
00110
00111 void DatabaseWizard::createDatabaseEnable()
00112 {
00113 createDatabaseButton->setEnabled( !databaseEdit->text().isEmpty() );
00114 setNextEnabled( createDatabasePage, false );
00115 createUserEnable();
00116 }
00117
00118
00119 void DatabaseWizard::createDatabase()
00120 {
00121 assert( serverRoot );
00122 assert( !databaseEdit->text().isEmpty() );
00123
00124
00125 clientEdit->setText( ( serverEdit->text() == "localhost" ||
00126 serverTypeCombo->currentItem() == 1 ) ?
00127 "localhost" : "%" );
00128
00129 try {
00130
00131 std::ostringstream createQuery;
00132 createQuery << "CREATE DATABASE " << databaseEdit->text()
00133 << " DEFAULT CHARACTER SET utf8;";
00134
00135 bool exist = false;
00136
00137
00138 if ( mysql_query( serverRoot->getConnection(),
00139 createQuery.str().c_str() ) != 0 ) {
00140 if ( mysql_errno( serverRoot->getConnection() ) == ER_DB_CREATE_EXISTS )
00141 exist = true;
00142 else {
00143
00144
00145 std::ostringstream createQuery;
00146 createQuery << "CREATE DATABASE " << databaseEdit->text() << ';';
00147 if ( mysql_query( serverRoot->getConnection(),
00148 createQuery.str().c_str() ) != 0 ) {
00149 if ( mysql_errno( serverRoot->getConnection() ) == ER_DB_CREATE_EXISTS )
00150 exist = true;
00151 else
00152 ERRORMACRO( false,
00153 Error, , i18n( "Error creating database: %1" ).
00154 arg( mysql_error( serverRoot->getConnection() ) ) );
00155 };
00156
00157 KMessageBox::sorry( this,
00158 i18n( "Could not configure database to use "
00159 "UTF-8 character set. "
00160 "If you want a UTF-8-aware database, you "
00161 "should upgrade to MySQL 4.1 or higher." ) );
00162 };
00163 };
00164
00165 if ( exist )
00166 ERRORMACRO( KMessageBox::warningContinueCancel
00167 ( this,
00168 i18n( "Database '%1' seems to be existing already. "
00169 "Do you want to use it?" ).
00170 arg( databaseEdit->text() ) ) == KMessageBox::Continue,
00171 Error, ,
00172 i18n( "Database '%1' is existing already." ).
00173 arg( databaseEdit->text() ) );
00174
00175 try {
00176
00177
00178 CookBook cookBook
00179 ( DatabasePtr( new MySQLDatabase
00180 ( serverRoot, databaseEdit->text() ) ),
00181 findAnyMealFile( "appdata", "scripts/mysqlIn.xsl" ),
00182 findAnyMealFile( "appdata", "scripts/mysqlOut.xsl" ),
00183 exist );
00184
00185
00186 if ( !exist ) {
00187 DisplayWaitCursor w;
00188 std::string query( "<?xml version='1.0' encoding='UTF-8'?><create/>" );
00189 cookBook.getXMLLayer()->translate( query );
00190 };
00191
00192 } catch ( CookBookDeprecated &e ) {
00193
00194
00195 int version = e.getVersion();
00196
00197 if ( KMessageBox::warningContinueCancel
00198 ( this,
00199 i18n( "Do you want to update the database "
00200 "from version %1 to version %2? "
00201 "It is recommended to do a backup "
00202 "before." ).
00203 arg( versionText( version ) ).
00204 arg( versionText( DATABASEVERSION ) ),
00205 i18n( "Update Database" ) ) == KMessageBox::Continue ) {
00206
00207 DisplayWaitCursor w;
00208
00209
00210 CookBook cookBook
00211 ( DatabasePtr( new MySQLDatabase
00212 ( serverRoot, databaseEdit->text() ) ),
00213 findAnyMealFile( "appdata", "scripts/mysqlIn.xsl" ),
00214 findAnyMealFile( "appdata", "scripts/mysqlOut.xsl" ),
00215 false );
00216
00217 cookBook.update();
00218
00219 } else
00220 throw e;
00221
00222 };
00223
00224
00225 createDatabaseButton->setEnabled( false );
00226
00227 setNextEnabled( createDatabasePage, true );
00228
00229 } catch ( std::exception &e ) {
00230
00231 KMessageBox::error( this, e.what() );
00232
00233 };
00234
00235 }
00236
00237
00238 void DatabaseWizard::createUserEnable()
00239 {
00240
00241
00242 createUserButton->setEnabled
00243 ( !databaseUserEdit->text().isEmpty() &&
00244 ( !databasePassWordCheckBox->isChecked() ||
00245 ( !databasePassWordEdit->text().isEmpty() &&
00246 databasePassWordEdit->text() ==
00247 databasePassWordConfirmEdit->text() ) ) );
00248 setNextEnabled( createUserPage, false );
00249 }
00250
00251
00252 void DatabaseWizard::createUser()
00253 {
00254 assert( serverRoot );
00255
00256 try {
00257
00258 assert( !databaseUserEdit->text().isEmpty() );
00259 assert( !databasePassWordCheckBox->isChecked() ||
00260 !databasePassWordEdit->text().isEmpty() );
00261
00262 DisplayWaitCursor w;
00263
00264 std::ostringstream grantQuery;
00265 grantQuery << "GRANT ALL ON " << databaseEdit->text() << ".* TO "
00266 << databaseUserEdit->text();
00267 if ( !clientEdit->text().isEmpty() )
00268 grantQuery << "@'" << clientEdit->text() << '\'';
00269 if ( databasePassWordCheckBox->isChecked() ) {
00270 assert( !databasePassWordEdit->text().isEmpty() );
00271 grantQuery << " IDENTIFIED BY '" << databasePassWordEdit->text() << "'";
00272 };
00273 grantQuery << ';';
00274
00275 ERRORMACRO( !mysql_query( serverRoot->getConnection(),
00276 grantQuery.str().c_str() ), Error, ,
00277 i18n( "Error setting up database account: %1" ).
00278 arg( mysql_error( serverRoot->getConnection() ) ) );
00279
00280
00281 switch ( serverTypeCombo->currentItem() ) {
00282 case 0:
00283 serverUser = MySQLServerPtr
00284 ( new MySQLNetwork( databaseUserEdit->text(),
00285 databasePassWordCheckBox->isChecked() ?
00286 (const char *)databasePassWordEdit->text() : "",
00287 serverEdit->text(), MYSQL_PORT ) );
00288 break;
00289 case 1:
00290 assert( daemon );
00291 serverUser = MySQLServerPtr
00292 ( new MySQLSocket( databaseUserEdit->text(),
00293 databasePassWordCheckBox->isChecked() ?
00294 (const char *)databasePassWordEdit->text() : "",
00295 socketEdit->text(), daemon ) );
00296 break;
00297 default:
00298 assert( false );
00299 };
00300
00301
00302 MySQLDatabase( serverUser, databaseEdit->text() );
00303
00304
00305 createUserButton->setEnabled( false );
00306
00307 setNextEnabled( createUserPage, true );
00308
00309 } catch ( std::exception &e ) {
00310
00311 KMessageBox::error( this, e.what() );
00312
00313 };
00314 }
00315
00316
00317 void DatabaseWizard::importRecipes()
00318 {
00319 assert( serverUser );
00320
00321 try {
00322
00323 ImportMealMasterDialog importMealMasterDialog( this );
00324 importMealMasterDialog.databaseWizard = true;
00325 importMealMasterDialog.cookBook = CookBookPtr
00326 ( new CookBook
00327 ( DatabasePtr( new MySQLDatabase
00328 ( serverUser, databaseEdit->text() ) ),
00329 findAnyMealFile( "appdata", "scripts/mysqlIn.xsl" ),
00330 findAnyMealFile( "appdata", "scripts/mysqlOut.xsl" ) ) );
00331 importMealMasterDialog.exec();
00332
00333 } catch ( std::exception &e ) {
00334
00335 KMessageBox::error( this, e.what() );
00336
00337 };
00338 }
00339
00340
00341 void DatabaseWizard::selectSocket()
00342 {
00343 QString fileName =
00344 KFileDialog::getOpenFileName( ":dbfolder",
00345 i18n( "*.sock|Socket (*.sock)\n"
00346 "*|All Files(*)" ),
00347 this,
00348 i18n( "Select database socket" ) );
00349 if ( fileName != QString::null ) {
00350 socketEdit->setText( fileName );
00351 };
00352 }
00353
00354 const std::string &DatabaseWizard::createDatabase( const std::string &dir )
00355 {
00356 if ( testFile( dir + "/mysql" ) != EISDIR ) {
00357 ERRORMACRO( KMessageBox::questionYesNo
00358 ( this, i18n( "Directory '%1' does not exist. Should the "
00359 "database be created?" ).arg( dir ),
00360 i18n( "Database does not exist" ) ) == KMessageBox::Yes,
00361 Error, ,
00362 "Database '" << dir << "' does not exist." );
00363 std::string info = MySQLDaemon::create( dir, dir + "/mysql.sock" );
00364 KMessageBox::information( this, info, i18n( "Installation log" ) );
00365 };
00366 return dir;
00367 }
00368
00369
00370 void DatabaseWizard::socketChanged( const QString &_s )
00371 {
00372 std::string socket( (const char *)_s );
00373 unsigned int pos = socket.find_last_of( "/" );
00374 if ( pos != std::string::npos )
00375 folderEdit->setText( std::string( socket, 0, pos ).c_str() );
00376 }