I need a struct or something similar to it but what and how?



  • I know that this is not a Qt questions and is more like a c++ but here I am.
    what I want to archive is to get something like this:
    @ echo databaseTable // list of all tables from this database @
    @ echo databaseTable.tableName // list of all fields from this database table@
    @ echo databaseTable.tableName.fieldName // name of that specific field@

    eg.
    I have two database:db1 and db2.

    db1 with following tables: table1 and table2 and table3
    db2 with following tables: table1a and table2a and table3a

    Table1 fields: id, name, comp
    Table2 fields: id, book, author
    Table3 fields: id, field1, field2

    Table1a fields: id, fieldName, fieldName1
    Table2a fields: id, fieldName2, fieldName4
    Table3a fields: id, fieldName, field2

    so @echo databaseTable // will output db1, db2@
    so @echo databaseTable['db1']
    or
    echo databaseTable.db1
    // will output table1, table2, table3@

    @echo databaseTable['db1']['table2']
    or
    echo databaseTable.db1.table2
    will output: id, book, author
    @

    and so on..

    here is the basic thing that I wish to make it if it will be possible. is an array in array?? like in php? any other data type??
    Thanks for your help..


  • Lifetime Qt Champion

    Hi,

    Since it's not even c/c++ code, I assume it's pseudo code. What you would need is a set of classes that encapsulate each element. One class for the database itself and one for the table. Then it's up to you to provide the accessors your want.

    Hope it helps



  • can you give me a small example please. so the return of each can be QString and QStringList since some have only one table name or db name like @db("main") will return "nameOfMainDb.db"@ or @db("main").table @ will give a QStringList with a list of tables names.
    and @db("main").table("config")@ cand give a result of QStrings as config_tbl or settings_tbl or what ever the user set it t be. and then getting the fields name all like
    @db("main").table(settings).fields@ result QStringList (id, name, parameter, on_off, start_up) but if I call

    @db("main").table(settings).fields("id")@ will return QString "id" or it can be "settings_id" or "confing_id" and so on

    yes all this was pseudo code to give you the idea what i'm looking for.
    echo = cout so I will have to be able to cout those functions and vars.


  • Lifetime Qt Champion

    Then only use QStringList has return type. A list with one element is still a list.

    What example are you thinking about ?



  • I do not know how can I do a such class that can be accessed like in my example. I know how to do it like @
    MyDbClass myDb;
    myDb.getDbNames();@
    but how can I do it to work like this...
    @db("main").table@ or
    @db("main").table("settings").fildsName@ or
    @db("main").table("settings").fildsName("id")@

    can you help me too do such thing? how Qt is doing with QFile..
    file.open() or like tableView.model.data(); how those different classes can be linked together? and to communicate...


  • Lifetime Qt Champion

    @
    MyDbConnection myDbConnection<< looks like QSqlDatabase

    QStringList dataBaseList = myDbConnection.databaseNames();

    MyDbClass myDb(dataBaseList.first());
    QStringList tableList = myDb.tableList();
    MyDbTable = myDb.table(tableList.first());
    etc…
    @

    Then you need to implement e.g. QTextStream operator for your classes and also QDebug operator for debug purposes.



  • thanks.. that is nearly what I've been thinking.. any way I will implement a work around this... without being able to do what I've had into my head. this things is very useful for me because my app will work on Linux and Windows. and in the setup process - first time run - or when all the ini file's are missing to setup the database and the database tables. I'm working with 3 different tables type and many connections. I have the main database - the one that keep the program running and all the company evidence. second is a company database - that keep all the data for the clients - general data. - those can be also many connections because it can have many company. and are many database distinct files. and also the third type is the client database - each client database is indivifual sqlite database for the client with details about that client. this is relating to the company connection. so if you are connected to a certain company you can not access data from other company even if is a different file on hdd. and for that reason I need to have stored some constants that to be accessible when the user create a new company - I have to create the table structure and a new client , where I also have to create a new structure witch in many cases is similar one to another the main difference is the database file name.
    So @QStringList dataBaseList = myDbConnection.databaseNames();@ will return only the active connections and this thing is not something that I'm looking about.
    I wish to be able to access the database structure or table structure of a possible connection that is not already made and I wish to create now new.


  • Lifetime Qt Champion

    So you want to access details that would require admin privilege without even making a connection to a remote database ? Or are you targeting only sqlite ?



  • I'm targeting only sqlite. the thing is that always when the user add a new company or a new client I have to create the structure for that (some files and databases). the main databases keep record of this. now imagine that I have multiple files and different structure of the tables (as already explained I have 3 different types of structure at the moment) and ... here is an example
    @void AtpCompanyEdit::onButtonNewClicked(){
    QString buttonName;
    buttonName = ui->buttonNew->text();
    if ( buttonName == "New"){
    ui->enableAndDisable("new");
    seEediteaza = true;
    eNou = true;
    } else {
    data->clear();
    data->insert(":comp_name", ui->editCompany->text());
    data->insert(":comp_addres", ui->editAddress->document()->toPlainText());
    data->insert(":comp_www", ui->editWebsite->text());
    data->insert(":comp_director", ui->editDirector->text());
    data->insert(":comp_tel", ui->editTel->text());
    data->insert(":comp_mob", ui->editMob->text());
    data->insert(":comp_email", ui->editMail->text());
    QString companyFileName = ui->editCompany->text().remove(" ");
    if ( companyFileName.isNull() || companyFileName.isEmpty()){
    QString mainWindowTitle = "Create new Company";
    QString infoText = "Company name can not be empty!";
    QMessageBox msgBox;
    msgBox.setWindowTitle(mainWindowTitle);
    msgBox.setText("Company name is empty.");
    msgBox.setInformativeText(infoText);
    msgBox.setStandardButtons(QMessageBox::Yes);
    msgBox.setDefaultButton(QMessageBox::Yes);
    msgBox.exec();
    return;
    }
    data->insert(":comp_file", companyFileName);
    AtpSqlQuery::atpInsert("main", "m_company_t", data);
    QString newDbPath = AtpSettings::getCompanyPath(companyFileName, true);
    AtpDbComp::createCompanyStructure(newDbPath, companyFileName);

    updateDb();
    }
    }@ this is the button that add a new company this is the

    • enableAndDisable
      @void enableAndDisable(QString condition){
      if (condition == "reset"){
      enableAndDisable("resetButtons");
      enableAndDisable("disableFields");
      enableAndDisable("clearFields");
      } else if (condition == "resetButtons"){
      buttonNew->setText("New");
      buttonNew->setEnabled(true);
      buttonEdit->setText("Edit");
      buttonEdit->setEnabled(false);
      buttonDelete->setEnabled(false);
      } else if (condition == "disableFields"){
      editAddress->setEnabled(false);
      editCompany->setEnabled(false);
      editDirector->setEnabled(false);
      editMail->setEnabled(false);
      editMob->setEnabled(false);
      editTel->setEnabled(false);
      editWebsite->setEnabled(false);
      editSearch->setEnabled(true);
      editSearch->clear();
      tableViewCompany->setEnabled(true);
      } else if (condition == "enableFields"){
      editAddress->setEnabled(true);
      editCompany->setEnabled(true);
      editDirector->setEnabled(true);
      editMail->setEnabled(true);
      editMob->setEnabled(true);
      editTel->setEnabled(true);
      editWebsite->setEnabled(true);
      editSearch->setEnabled(false);
      tableViewCompany->setEnabled(false);
      } else if (condition == "clearFields"){
      editAddress->clear();
      editCompany->clear();
      editDirector->clear();
      editMail->clear();
      editMob->clear();
      editTel->clear();
      editWebsite->clear();
      editSearch->clear();
      tableViewCompany->clearSelection();
      } else if (condition == "edit"){
      buttonEdit->setText("Save");
      buttonDelete->setEnabled(false);
      buttonNew->setEnabled(false);
      enableAndDisable("enableFields");
      } else if (condition == "new") {
      buttonNew->setText("Save");
      buttonDelete->setEnabled(false);
      buttonEdit->setEnabled(false);
      editSearch->setEnabled(false);
      enableAndDisable("clearFields");
      enableAndDisable("enableFields");
      }
      }@
    • atpInsert
      @QSqlQuery AtpSqlQuery::atpInsert(QString dbName, QString tableName, QMap<QString, QVariant> data) {
      QString fieldNames, fieldValues, temp;
      QMap<QString, QVariant>::const_iterator i1;
      for (i1 = data->constBegin(); i1 != data->constEnd(); ++i1) {
      temp = i1.key();
      fieldValues += temp + ", ";
      fieldNames += temp.remove(0,1) + ", ";
      }
      fieldNames.remove(fieldNames.lastIndexOf(","),1);
      fieldValues.remove(fieldValues.lastIndexOf(","),1);
      // qDebug() << fieldNames << "
      * - **" << fieldValues;

    QSqlQuery myQuerry = QSqlQuery(getDbConnection(dbName));
    myQuerry.prepare("INSERT INTO " + tableName + " ( " + fieldNames + ") VALUES ( " + fieldValues + ")");
    // qDebug() << data;
    QMap<QString, QVariant>::const_iterator i;
    for (i = data->constBegin(); i != data->constEnd(); ++i) {
    myQuerry.bindValue(i.key(), i.value());
    //myQuerry.bindValue(i.key().toUtf8().data(), i.value().toString().toUtf8().data());
    }
    // qDebug() << myQuerry.boundValues();
    myQuerry.exec();
    qDebug() << myQuerry.lastQuery() <<myQuerry.lastError();
    return myQuerry;
    }@



    • get database
      @QSqlDatabase AtpSqlQuery::getDbConnection(QString connectionName){
      if (connectionName == "main"){
      return AtpDbMain::getDataBase();
      } else if (connectionName == "comp") {
      return AtpDbComp::getDataBase();
      } else if(connectionName == "client") {
      return AtpDbClient::getDataBase();
      }
      return QSqlDatabase::addDatabase("","noConnection");
      }@
    • update db - for view propose only
      @void AtpCompanyEdit::updateDb() {
      ui->enableAndDisable("reset");
      resetVars();

    model->setTable("m_company_t");
    //here I need to be
    /*
    model->setTable(db("main").table(company));
    because the name can be different and it may be possible not to be connected {not here because here the connection is already made but I have another place where the connection is not made}

    */
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->setHeaderData(0, Qt::Horizontal,"Id");
    model->setHeaderData(1, Qt::Horizontal,"Name");
    model->setHeaderData(2, Qt::Horizontal,"Address");
    model->setHeaderData(3, Qt::Horizontal,"Website");
    model->setHeaderData(4, Qt::Horizontal,"Director");
    model->setHeaderData(5, Qt::Horizontal,"Telephone");
    model->setHeaderData(6, Qt::Horizontal,"Mobile");
    model->setHeaderData(7, Qt::Horizontal,"E-mail");

    proxyModel = new QSortFilterProxyModel(this);
    proxyModel->setSourceModel(model);
    proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);

    ui->tableViewCompany->setModel(proxyModel);
    ui->tableViewCompany->setSortingEnabled(true);
    ui->tableViewCompany->setColumnHidden(0, true);
    ui->tableViewCompany->setColumnWidth(1, 100);
    ui->tableViewCompany->setColumnWidth(2, 250);
    ui->tableViewCompany->setColumnWidth(3, 150);
    ui->tableViewCompany->setColumnWidth(4, 150);
    ui->tableViewCompany->setColumnWidth(5, 150);
    ui->tableViewCompany->setColumnWidth(6, 150);
    ui->tableViewCompany->setColumnWidth(7, 150);
    ui->tableViewCompany->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableViewCompany->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tableViewCompany->setAlternatingRowColors(true);
    model->select();
    }@

    • main db

    @bool AtpDbMain::createMainSQLiteDb(QString dbNewPath, QString dbNewType) {
    uninit();
    QSqlDatabase myNewdb;
    if (!isDriverAvailable(dbNewType)){
    return false;
    }
    myNewdb = QSqlDatabase::addDatabase(dbNewType, "mainDbConnection");
    qDebug() << dbNewType;
    myNewdb.setDatabaseName(dbNewPath);
    if (!myNewdb.open()){
    qCritical() << "couldn't connect to database Error[" << myNewdb.lastError().text() << "]" << dbPath;
    return false;
    } else {
    qDebug() << "succsessfully connected to database " << dbPath;
    }
    qDebug() << "DB 1";
    QVector<QString> tables(0);
    tables.append("CREATE TABLE m_login_t (login_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, login_username text, login_password text);");
    tables.append("CREATE TABLE m_company_t (comp_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, comp_name text, comp_addres text, comp_www text, comp_director text, comp_tel text, comp_mob text, comp_email text, comp_file text);");
    // tables.append("CREATE TABLE m_client_list_tbl(client_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, client_name text, client_address text, client_tel text, client_mob text, client_email text, client_file text);");
    // tables.append("CREATE TABLE m_for_tbl (for_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, for_name text);");
    tables.append("CREATE TABLE m_group_place_t (group_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, group_place text, group_parent integer);");
    // tables.append("CREATE TABLE m_invoice_tbl (inv_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, inv_quote_id integer, inv_date date, inv_for_id integer, inv_value real);");
    // tables.append("CREATE TABLE m_materiale_tbl ( mat_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, mat_name text, mat_price1 real, mat_price2 real, mat_supplier_id integer);");
    // tables.append("CREATE TABLE m_plata_tbl (plata_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, plata_detalii text);");
    // tables.append("CREATE TABLE m_punct_price ( punct_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, punct_name text, punct_price1 real, punct_price2 real);");
    // tables.append("CREATE TABLE m_quotation_detail_tbl (qd_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, qd_q_id integer, qd_item_place integer, qd_price_id integer, qd_quantity1 integer, qd_quantity2 integer, qd_note text);");
    // tables.append("CREATE TABLE m_quotation_tbl (q_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, q_client_id integer, q_company_id integer, q_data date, q_price1 real, q_price2 real, q_price3 real, q_mytotal real);");
    // tables.append("CREATE TABLE m_receipt (re_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, re_inv_id integer, re_total real, re_client_id integer, re_comp_id integer);");
    // tables.append("CREATE TABLE m_receipt_detail_tbl (red_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, red_re_id integer, red_data date, red_amount real, red_detail integer, red_note text);");
    // tables.append("CREATE TABLE m_supplier_tbl (supplier_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, supplier_name text, supplier_addres text, supplier_telephon text, supplier_mob text, supplier_email text, supplier_web text);");
    QSqlQuery myquerry = QSqlQuery(myNewdb);
    for (int i = 0; i < tables.size(); ++i) {
    myquerry.exec(tables[i]);
    qDebug() << myquerry.lastQuery();
    qDebug() << myquerry.lastError();
    }
    mydb = myNewdb;
    return true;
    }@

    here the connection is not made and I wish to be able to change the values of the fields and of the tables and to have control on them.. so because it will be 3 different types of the structures you can see that I've commented out what I do not need in main. but I know that I can write 3 function of create but.... just for the sake of doing it... maybe in the future I will have more then 3 and I wish too prevent that and too have something flexible.
    thanks


  • Lifetime Qt Champion

    I'm not sure I'm following your correctly. Are you telling that you create a complete new database for each client and company added ?



  • yes. the structure is like that I have the databse filder. inside it is the main database file and folders for each company. inside company folder you have the main company database file and all clients files. reason behind this is that the data from a company is totally different from another company. also inside same company clients receive the very same goods but with different prices and it need to have a different database file.

    @bool AtpDbClient::createClientStructure(QString dbNewPath, QString dbNewFileName, QString dbNewType){
    QSqlDatabase myNewdb;
    if (!isDriverAvailable(dbNewType)){
    return false;
    }
    dbNewPath = dbNewPath + "/" + dbNewFileName.append(".atpdb");
    myNewdb = QSqlDatabase::addDatabase(dbNewType, "clientDbConnection");
    myNewdb.setDatabaseName(dbNewPath);
    if (!myNewdb.open()){
    qCritical() << "couldn't connect to database Error[" << myNewdb.lastError().text() << "]" << dbPath;
    return false;
    } else {
    qDebug() << "succsessfully connected to database " << dbPath;
    }
    QVector<QString> tables(0);

    // tables.append("CREATE TABLE cl_for_tbl (for_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, for_name text);");
    // tables.append("CREATE TABLE cl_group_tbl (group_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, group_place text);");
    // tables.append("CREATE TABLE cl_invoice_tbl (inv_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, inv_quote_id integer, inv_date date, inv_for_id integer, inv_value real);");
    tables.append("CREATE TABLE cl_materiale_t ( mat_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, mat_name text, mat_price1 real, mat_price2 real, mat_supplier_id integer);");
    // tables.append("CREATE TABLE cl_plata_tbl (plata_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, plata_detalii text);");
    tables.append("CREATE TABLE cl_point_price_t ( punct_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, punct_name text, punct_price1 real, punct_price2 real);");
    tables.append("CREATE TABLE cl_quotation_detail_t (qd_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, qd_q_id integer, qd_item_place integer, qd_price_id integer, qd_quantity1 integer, qd_quantity2 integer, qd_note text);");
    // tables.append("CREATE TABLE cl_quotation_t (q_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, q_client_id integer, q_company_id integer, q_data date, q_price1 real, q_price2 real, q_price3 real, q_mytotal real);");
    // tables.append("CREATE TABLE cl_receipt_t (re_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, re_inv_id integer, re_total real, re_client_id integer, re_comp_id integer);");
    tables.append("CREATE TABLE cl_receipt_detail_t (red_id integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, red_re_id integer, red_data date, red_amount real, red_detail integer, red_note text);");

    QSqlQuery myquerry = QSqlQuery(myNewdb);
    for (int i = 0; i < tables.size(); ++i) {
    myquerry.exec(tables[i]);
    qDebug() << myquerry.lastQuery();
    qDebug() << myquerry.lastError();
    }
    clientDB = myNewdb;
    return true;
    }@
    like that is created every client file


  • Lifetime Qt Champion

    That kind of defeats the purpose of using a database. In the end, all your companies use the same tables.

    You should rather design your database so that you can put all your data in it.



  • no this is not true. only the main table is used by all companies. but the data that a company can access is different then the another one and also is it can have the same products but with different price and also the same company can raise the price.. but for an old transaction it have not to make that change. for this reason I have the company table and also the client table.. even if a company decided to have a price for one client and another price for another one.. the individual price will be saved on client database. the tables are different and also the content.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.