[Qt/C++] Wiele połączeń z bazą danych - błędy

0

Mam prosta aplikacje w Qt dzialajaca na tej zasadzie - ktos klika w menu, otwiera sie okienko, w ktore wprowadza dane, dane sa zapisywane do bazy. Po zamknieciu okienka (i programu) baza dalej istnieje, nie usuwam jej - tak trzymam sobie dane wstawione przez uzytkownika.

Mam pewien probem z tym - i juz kompletnie brak sil, aby to sensownie rozwiazac :/ nie odsylajcie mnie blagam do google (chyba juz cale przeszukalem :p wpisujac: multiply database connections qt) i zero rezultatow, ktore by mi pomogly ... Chodzi o to, ze jak user za 1 razem klika, wprowadza dane, zapisuja sie. Potem, kolejnym razem, dostaje taki komunikat:

QSqlDatabasePrivate::addDatabase: duplicate connection name 'nazwaBazy', old connection removed.
QSqlQuery::exec: database not open
"table nazwaTabeli already exists" 
"Unable to execute statement" 

no i jak latwo sie domyslic, nic sie nie zapisuje ...

A do bazy wpisuje tak:

        mojaBaza = QSqlDatabase::addDatabase("QSQLITE", "daneOs");
        mojaBaza.setHostName("localhost");
        mojaBaza.setDatabaseName("./daneOs.gdb");
        mojaBaza.setUserName("Administrator");
        mojaBaza.setPassword("dupa.8"); 

        if (!mojaBaza.open()) {
            QMessageBox::critical(0, QObject::tr("Database Error"),mojaBaza.lastError().text());
            exit(1);
          }

        QSqlQueryModel modelCreate;
        modelCreate.setQuery("select * from mojaTabela");
        QSqlQuery query(registeredUsersDb);

        if(modelCreate.record().isEmpty())
        {
         query.exec("create table mojaTabela (id integer primary key autoincrement, " "imie varchar(40), nazwisko varchar(60), adres varchar(80))");
         qDebug() << query.lastError().databaseText();
         qDebug() << query.lastError().driverText();

         query.prepare("insert into mojaTabela values(:id,:imie,:nazwisko,:adres)");
         query.bindValue(":imie",getImie());
         query.bindValue(":nazwisko",getNazwisko());
         query.bindValue(":adres",getAdres());
         query.exec();
         qDebug() << query.lastError().databaseText();
         qDebug() << query.lastError().driverText();

         if(mojaBaza.isOpen())
         {
          mojaBaza.close();
         }
        }
        else
        {
          query.prepare("insert into mojaTabela values(:id,:imie,:nazwisko,:adres)");
         query.bindValue(":imie",getImie());
         query.bindValue(":nazwisko",getNazwisko());
         query.bindValue(":adres",getAdres());
         query.exec();
         qDebug() << query.lastError().databaseText();
         qDebug() << query.lastError().driverText();

         if(mojaBaza.isOpen())
         {
          mojaBaza.close();
         }
        }

Blagam ... pomóżcie ;)

0
ratujcie napisał(a)

Chodzi o to, ze jak user za 1 razem klika, wprowadza dane, zapisuja sie. Potem, kolejnym razem, dostaje taki komunikat:

Czyli cały ten kod jest jedną metodą uruchamianą za każdym razem, gdy user klika aby wprowadzić dane?

Jeśli tak, to addDatabase i pozostałą inicjalizację bazy przenieś do innej metody, co do której masz pewność że zostanie wywołana raz i zanim user będzie mógł klikać aby wprowadzać dane.

Btw. Używasz, bądź używałeś php?

0

Nie. Robie to w ten sposob - mam klase do wprowadzania danych, ktora dziedziczy po QDialog, nazwijmy ja np. wprowadzDane. W konstruktorze tej klasy mam dodawanie bazy, czyli kawalek ten:

wprowadzDane::wprowadzDane(){

mojaBaza = QSqlDatabase::addDatabase("QSQLITE", "daneOs");
mojaBaza.setHostName("localhost");
mojaBaza.setDatabaseName("./daneOs.gdb");
mojaBaza.setUserName("Administrator");
mojaBaza.setPassword("dupa.8");

    if (!mojaBaza.open()) {
        QMessageBox::critical(0, QObject::tr("Database Error"),mojaBaza.lastError().text());
        exit(1);
      }

//cos tam

}

Mam tez funkcje wpiszDoBazy(), wyglada ona tak:

void wpiszDoBazy(){
QSqlQueryModel modelCreate;
        modelCreate.setQuery("select * from mojaTabela");
        QSqlQuery query(registeredUsersDb);

        if(modelCreate.record().isEmpty())
        {
         query.exec("create table mojaTabela (id integer primary key autoincrement, " "imie varchar(40), nazwisko varchar(60), adres varchar(80))");
         qDebug() << query.lastError().databaseText();
         qDebug() << query.lastError().driverText();

         query.prepare("insert into mojaTabela values(:id,:imie,:nazwisko,:adres)");
         query.bindValue(":imie",getImie());
         query.bindValue(":nazwisko",getNazwisko());
         query.bindValue(":adres",getAdres());
         query.exec();
         qDebug() << query.lastError().databaseText();
         qDebug() << query.lastError().driverText();

         if(mojaBaza.isOpen())
         {
          mojaBaza.close();
         }
        }
        else
        {
          query.prepare("insert into mojaTabela values(:id,:imie,:nazwisko,:adres)");
         query.bindValue(":imie",getImie());
         query.bindValue(":nazwisko",getNazwisko());
         query.bindValue(":adres",getAdres());
         query.exec();
         qDebug() << query.lastError().databaseText();
         qDebug() << query.lastError().driverText();

         if(mojaBaza.isOpen())
         {
          mojaBaza.close();
         }
        }
}

Za kazdym razem, kiedy user wypelni pola, wscisnie przycisk, wywolywana jest moja metoda wpiszDoBazy();

Mam tez klase glowna, mainWindow, gdzie po kliknieciu w menu "wspisz dane osobowe" mam w.exec(); gdzie w jest obiektem klasy wprowadzDane.

wprowadzDane w; 
w.exec();

no i reszta sie odbywa w okienku "wprowadzDane" ... juz nie wiem, co zrobic z tym :/ A co do PHP - niestety, nie uzywalem, i na razie nie mam czasu sie nawet w nim rozejrzec ;)

0

Hmmm jeszcze raz przeczytalem, to co napisałeś - nasuwa mi się jedno rozwiązanie - aby moja baza była w klasie mainWindow QSqlDatabase mojaBaza; a nie, tak jak mam teraz, w klasie wprowadz dane - bylaby wtedy tylko raz inicjalizowana, w konstruktorze klasy mainWindow odpowiedzialnej za caly program ... tylko to chyba tak średnio elegancko, co nie ? ;)

0
ratujcie napisał(a)

Hmmm jeszcze raz przeczytalem, to co napisałeś - nasuwa mi się jedno rozwiązanie - aby moja baza była w klasie mainWindow QSqlDatabase mojaBaza; a nie, tak jak mam teraz, w klasie wprowadz dane - bylaby wtedy tylko raz inicjalizowana, w konstruktorze klasy mainWindow odpowiedzialnej za caly program ... tylko to chyba tak średnio elegancko, co nie ? ;)

No w przykładzie http://doc.trolltech.com/4.7/sql-masterdetail.html bazę danych inicjalizują wywołując z maina funkcję statyczną. Bo potem mozna tą bazę otrzymać poprzez nazwę jaką nadaliśmy połączeniu i metodzie statycznej database http://doc.trolltech.com/4.7/qsqldatabase.html#database

Podaj jaki efekt spowoduje wykomentowanie kodu zamykającego bazę danych w metodzie wpiszDoBazy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1