QVariant RelationalProxyModel::getRelationData(QModelIndex index) const { int column = index.column(); if (not m_relations.contains(column)) return QVariant(); const QSqlRelation relation = m_relations[column]; QVariant related_id = sourceModel()->data(mapToSource(index)); QSqlDriver *driver = QSqlDatabase::database().driver(); QSqlRecord search_record; search_record.append(QSqlField(relation.indexColumn(), QVariant::Int)); search_record.setValue(relation.indexColumn(), QVariant(related_id.toInt())); QString where_statement = driver->sqlStatement(QSqlDriver::WhereStatement, relation.tableName(), search_record, false); QString select_statement = driver->sqlStatement(QSqlDriver::SelectStatement, relation.tableName(), QSqlDatabase::database().record(relation.tableName()), false); QSqlQuery query(QString("%1 %2").arg(select_statement, where_statement)); query.next(); if (not query.isValid()) return QVariant(); return query.record().value(relation.displayColumn()); }
QString TSqlQuery::escapeIdentifier(const QString &identifier, QSqlDriver::IdentifierType type) { QString ret = identifier; QSqlDriver *driver = TActionContext::currentDatabase().driver(); if (!driver->isIdentifierEscaped(identifier, type)) { ret = driver->escapeIdentifier(identifier, type); } return ret; }
QString TSqlQuery::escapeIdentifier(const QString &identifier, QSqlDriver::IdentifierType type, const QSqlDatabase &database) { QString ret = identifier; QSqlDriver *driver = database.driver(); if (!driver->isIdentifierEscaped(identifier, type)) { ret = driver->escapeIdentifier(identifier, type); } return ret; }
void deleteRecord(QString table, QSqlRecord record) { QSqlDriver *driver = QSqlDatabase::database().driver(); QString delete_statement = driver->sqlStatement(QSqlDriver::DeleteStatement, table, QSqlRecord(), false); QString where_statement = driver->sqlStatement(QSqlDriver::WhereStatement, table, record, false); QSqlQuery query(QString("%1 %2").arg(delete_statement, where_statement)); if (query.lastError().isValid()) throw new SqlQueryError(query); }
void SqlTransactionTests::testSqLiteDriverRequirements() { const char DriverName[] = "QSQLITE"; QVERIFY( QSqlDatabase::isDriverAvailable( DriverName ) ); QSqlDatabase db = QSqlDatabase::addDatabase( DriverName, "test-sqlite.charm.kdab.com" ); QSqlDriver* driver = db.driver(); QVERIFY( driver->hasFeature( QSqlDriver::Transactions ) ); }
QString formatSqlValue(QVariant value) { QSqlDatabase db = QSqlDatabase::database(); QSqlDriver *driver = db.driver(); QSqlField field("value", value.type()); field.setValue(value); return driver->formatValue(field, true); }
bool receiptsEngine::insertIntoAccount(const QHash<int,QVariant> &hashValues, const QString &userUuid) { // fetch all the account model /*while (m_mpmodel->canFetchMore(QModelIndex())) { if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__)<< " while "; m_mpmodel->QAbstractItemModel::fetchMore(QModelIndex()); }*/ QSqlDatabase db = QSqlDatabase::database(Constants::DB_ACCOUNTANCY); QSqlDriver *driver = db.driver(); if (driver->hasFeature(QSqlDriver::QuerySize)) { if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << "driver has feature"; } QString filterUser = QString("%1='%2'").arg("USER_UID",userUuid); m_mpmodel->AccountModel::setFilter(filterUser); int rowBefore = m_mpmodel->AccountModel::rowCount(QModelIndex()); if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " rowBefore = " << QString::number(rowBefore); if (m_mpmodel->insertRows(rowBefore,1,QModelIndex())) { qWarning() << __FILE__ << QString::number(__LINE__) << "Row inserted !" ; } bool ret = true; QVariant data; for(int i = 1 ; i < ACCOUNT_MaxParam ; i ++){ data = hashValues.value(i); if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " data + i =" << data.toString()+" "+QString::number(i); if (i == ACCOUNT_PATIENT_NAME) { QString dataString = data.toString(); dataString.replace("'","''"); data = QVariant(dataString); } if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " data after =" << data.toString()+" "+QString::number(i); if (!m_mpmodel-> setData(m_mpmodel->index(rowBefore,i), data ,Qt::EditRole)) { qWarning() << __FILE__ << QString::number(__LINE__) << " model account error = " << m_mpmodel->lastError().text() ; } } if (!m_mpmodel->AccountModel::submit()) { qWarning() << __FILE__ << QString::number(__LINE__) << " submit error = " << m_mpmodel->lastError().text() ; ret = false; } return ret; }
TableInfoModel* MigraineMainWindow::buildTreeModel(QSqlDatabase db) { QList<TableInfo*> data; QSqlDriver *driver = db.driver(); QStringList tables = db.tables(QSql::Tables); for(int i = 0; i < tables.count(); i++) { data << new TableInfo(tables.at(i), driver->record(tables.at(i))); } return new TableInfoModel(data); }
DatabaseCache::DatabaseCache(const Ice::CommunicatorPtr& communicator, const string& type, const string& name, const string& host, int port, const string& user, const string& password, bool requiresBlob) { Ice::PropertiesPtr properties = communicator->getProperties(); // // File lock to prevent multiple process open the same db env. // if(type == "QSQLITE") { _fileLock = new IceUtilInternal::FileLock(name + ".lock"); } _connection = QSqlDatabase::addDatabase(type.c_str(), IceUtil::generateUUID().c_str()); _connection.setDatabaseName(name.c_str()); _connection.setHostName(host.c_str()); if(port != 0) { _connection.setPort(port); } _connection.setUserName(user.c_str()); _connection.setPassword(password.c_str()); DatabaseConnectionPtr connection = DatabaseConnectionPtr::dynamicCast(getConnection()); QSqlDriver* driver = connection->sqlConnection().driver(); if(!driver->hasFeature(QSqlDriver::Transactions)) { throw Ice::InitializationException(__FILE__, __LINE__, "SQL database driver requires transaction support"); } if(!driver->hasFeature(QSqlDriver::Unicode)) { throw Ice::InitializationException(__FILE__, __LINE__, "SQL database driver requires unicode support"); } if(requiresBlob && connection->sqlConnection().driverName() != "QODBC" && !driver->hasFeature(QSqlDriver::BLOB)) { throw Ice::InitializationException(__FILE__, __LINE__, "SQL database driver requires blob support"); } }
QList<QSqlRecord> selectQuery(QString table, QSqlRecord values, QSqlRecord where) { QList<QSqlRecord> records; QSqlDriver *driver = QSqlDatabase::database().driver(); QString where_statement = driver->sqlStatement(QSqlDriver::WhereStatement, table, where, false); QString select_statement = driver->sqlStatement(QSqlDriver::SelectStatement, table, values, false); QSqlQuery query(QString("%1 %2").arg(select_statement, where_statement)); if (query.lastError().isValid()) throw new SqlQueryError(query); while (query.next()) records.append(query.record()); return records; }
QSqlDatabase Database::add(QString p_path, QString database_name) { setPath(p_path); m_database_name = database_name; if (path().isEmpty()) throw new NoDatabaseNameGiven; QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); // Check if driver has all required features QSqlDriver *driver = db.driver(); if (not driver->hasFeature(QSqlDriver::LastInsertId)) { throw new RequiredFeatuersMissing; } db.setDatabaseName(path()); return db; }
QSqlRecord findOne(QString table, QSqlRecord values, QSqlRecord where) { QSqlDriver *driver = QSqlDatabase::database().driver(); QString where_statement = driver->sqlStatement(QSqlDriver::WhereStatement, table, where, false); QString select_statement = driver->sqlStatement(QSqlDriver::SelectStatement, table, values, false); QSqlQuery query(QString("%1 %2").arg(select_statement, where_statement)); qDebug() << "Query:" << query.lastQuery(); if (query.lastError().isValid()) throw new SqlQueryError(query); if (query.next()) return query.record(); else return QSqlRecord(); }
QList<RelationalObjectRef> findMany(RelationalObjectRef type, QSqlRecord values, QSqlRecord where) { QList<RelationalObjectRef> results; QSqlDriver *driver = QSqlDatabase::database().driver(); QString where_statement = driver->sqlStatement(QSqlDriver::WhereStatement, type.table(), where, false); QString select_statement = driver->sqlStatement(QSqlDriver::SelectStatement, type.table(), values, false); QSqlQuery query(QString("%1 %2").arg(select_statement, where_statement)); if (query.lastError().isValid()) throw new SqlQueryError(query); while (query.next()) { QSqlRecord record = query.record(); results << RelationalObjectRef(type.table(),type.fieldName(), record.field("id").value().toInt()); } return results; }
/** * The constructor creates the db and the tables if required. There's a single instance of db for all * the ServerDatabase instances. */ ServerDatabase::ServerDatabase() { #ifdef _VERBOSE_DATABASE qDebug() << "Creating a new instance of the db connector: " << m_dbref; #endif if (!m_dbref++) { // manually load the driver (for some reason I couldn't figure out how to have it loaded automagically) QPluginLoader loader("libqsqlmysql.so"); if (loader.load()) { #ifdef _VERBOSE_DATABASE qDebug() << "Loaded mysql drivers plugin"; #endif } else { qDebug() << QObject::tr("Failed to load mysql drivers plugin: ") + loader.errorString(); return; } QSqlDriverPlugin *sqlPlugin = qobject_cast<QSqlDriverPlugin *>(loader.instance()); #ifdef _VERBOSE_DATABASE qDebug() << "Available sql drivers: " << sqlPlugin->keys(); #endif QSqlDriver *sqlDriver = sqlPlugin->create(DB_TYPE); if (!sqlDriver) { qDebug() << QObject::tr("Failed to instantiate mysql driver"); return; } sqlDriver->open(DB_NAME, DB_USR, DB_PWD, DB_HOST); if (sqlDriver->isOpenError()) { qDebug() << QObject::tr("Failed to connect to (") + DB_TYPE + QObject::tr(") DB ") + DB_NAME + QObject::tr(" on host ") + DB_HOST + QObject::tr(" with usr/pwd '") + DB_USR + "/" + DB_PWD + "'"; qDebug() << QObject::tr("ERROR: ") + sqlDriver->lastError().text(); return; } m_db = QSqlDatabase::addDatabase(sqlDriver); // create tables if non existing createTables(); } }
void SqlTransactionTests::testMySqlTransactionRollback() { MySqlStorage storage = prepareMySqlStorage(); QVERIFY( storage.database().open() ); QSqlDriver* driver = storage.database().driver(); QVERIFY( driver->hasFeature( QSqlDriver::Transactions ) ); QList<Task> tasksBefore = storage.getAllTasks(); QVERIFY( ! tasksBefore.isEmpty() ); Task first = tasksBefore.first(); // test a simple transaction that is completed and committed: { SqlRaiiTransactor transactor( storage.database() ); QSqlQuery query( storage.database() ); query.prepare("DELETE from Tasks where id=:id"); query.bindValue( "id", first.id() ); QVERIFY( storage.runQuery( query ) ); } // this transaction was NOT commited QList<Task> tasksAfter = storage.getAllTasks(); QVERIFY( ! tasksAfter.isEmpty() ); QVERIFY( tasksBefore == tasksAfter ); }
/* * Зберігаємо шаблон кросворду після редагування решітки */ void tableTemplateWidget::saveToDB() { int previewSizeCell = 20, val; int W = numCol*previewSizeCell; int H = numRow*previewSizeCell; QPainter *pngPainter = new QPainter(); QImage *image = new QImage(QSize(W, H), QImage::Format_ARGB32_Premultiplied); float t, l; QRectF src(0, 0, W, H); QRectF r; QTableWidgetItem *cell; QSqlQuery query; query.prepare("DELETE FROM crossword.grids WHERE _template = ?;"); query.addBindValue(QVariant(templateId)); query.exec(); QSqlError le = query.lastError(); if (le.type() != QSqlError::NoError) qDebug() << "saveToDB: " << le.text(); query.prepare("INSERT INTO crossword.grids (_template, _row, _column, _value) " "VALUES (?, ?, ?, ?)"); pb = new QProgressBar(this); pb->setRange(0, numRow*numCol); sb->addWidget(pb); QVariantList tmp, row, col, value; QString text; pngPainter->begin(image); int i, j, nw; for (i = 0; i < numRow; i++) { t = src.top() + i * previewSizeCell; for (j = 0; j < numCol; j++) { l = src.left() + j * previewSizeCell; r.setTop(t); r.setLeft(l); r.setRight(src.left() + l + previewSizeCell); r.setBottom(src.top() + t + previewSizeCell); cell = this->item(i, j); val = cell->data(Qt::UserRole).toInt(); if (val) pngPainter->fillRect(r, fullCell); else pngPainter->fillRect(r, emptyCell); // прямокутник для ячейки pngPainter->drawRect(r); // виводимо номер слова nw = findWordByRC(i, j) + 1; if ( nw >= 1 ) { text = QVariant(nw).toString(); pngPainter->drawText(r, Qt::AlignLeft | Qt::AlignTop, text); } tmp << templateId; row << i; col << j; value << val; } pb->setValue(i*numRow + j*numCol); } pngPainter->end(); query.addBindValue(tmp); query.addBindValue(row); query.addBindValue(col); query.addBindValue(value); QSqlDriver *drv = db->driver(); drv->beginTransaction(); query.execBatch(QSqlQuery::ValuesAsRows); drv->commitTransaction(); le = query.lastError(); if (le.type() != QSqlError::NoError) qDebug() << "saveToDB: " << le.text(); QByteArray ba; QBuffer blob(&ba); blob.open(QIODevice::ReadWrite | QIODevice::Unbuffered); image->save(&blob, "PNG"); blob.close(); /* * ====== Run before update DB ====== */ scanTemplate(); savePrivateData(); query.prepare("UPDATE crossword.templates SET _rows = ?, _columns = ?, " "_preview = ?, _count_words = ? WHERE _id = ?;"); query.addBindValue(QVariant(numRow)); query.addBindValue(QVariant(numCol)); query.addBindValue(QVariant(blob.data())); query.addBindValue(QVariant(wi.count())); query.addBindValue(QVariant(templateId)); query.exec(); le = query.lastError(); if (le.type() != QSqlError::NoError) qDebug() << "saveToDB: " << le.text(); delete image; delete pngPainter; sb->removeWidget(pb); sb->showMessage(tr("Template saved"), 2000); isDirty = false; // need for templateListWidget emit savedToDB(templateId); }
bool SqlTableModel::postRow(int row_no, bool throw_exc) { qfLogFuncFrame() << row_no; QF_ASSERT(m_table.isValidRowIndex(row_no), QString("row: %1 is out of range of rows (%2)").arg(row_no).arg(m_table.rowCount()), return false); qfu::TableRow &row_ref = m_table.rowRef(row_no); bool ret = true; if(row_ref.isInsert()) { qfDebug() << "\tINSERT"; //QSet<QString> referenced_foreign_tables = referencedForeignTables(); //int tbl_cnt = 0; qf::core::sql::Connection sql_conn = sqlConnection(); QSqlDriver *sqldrv = sql_conn.driver(); const QStringList table_ids = tableIdsSortedAccordingToForeignKeys(); for(QString table_id : table_ids) { qfDebug() << "\ttable:" << table_id; QSqlRecord rec; int i = -1; int serial_ix = -1; bool serial_ix_explicitly_set = false; int primary_ix = -1; //QSqlIndex pri_ix = ti.primaryIndex(); //bool has_blob_field = false; Q_FOREACH(const qf::core::utils::Table::Field &fld, row_ref.fields()) { i++; if(fld.tableId() != table_id) continue; //qfInfo() << table_id << "field:" << fld.name() << "is serial:" << fld.isSerial(); bool is_field_dirty = row_ref.isDirty(i); if(fld.isSerial()) { /// always include serial fields, an empty line cannot be inserted in other case //is_field_dirty = true; serial_ix = i; serial_ix_explicitly_set = is_field_dirty; qfDebug() << "\t serial ix:" << serial_ix; } if(fld.isPriKey()) { /// always include prikey field, an empty line cannot be inserted in other case //is_field_dirty = true; primary_ix = i; qfDebug() << "\t primary ix:" << primary_ix; } if(!is_field_dirty) continue; qfDebug() << "\tdirty field:" << fld.name(); QVariant v = row_ref.value(i); if(is_field_dirty) { /// null hodnotu nema smysl insertovat, pokud to neni nutne kvuli necemu jinemu /// naopak se pri insertu dokumentu z vice join tabulek muze stat, ze se vlozi to not-null fieldu null hodnota /// pokud je insert, join radek neexistuje, takze hodnoty jsou null a mysql v takovem pripade v resultsetu nastavi /// i not-null field na nullable QSqlField new_fld; //if(v.isNull() && fld.isSerial()) // v = 0; new_fld.setValue(v); //qfInfo() << "\t\t" << "val type:" << QVariant::typeToName(f.value().type()); new_fld.setName(fld.shortName()); rec.append(new_fld); } } qfDebug() << "updating table inserts" << table_id; QString qs; QString table = sql_conn.fullTableNameToQtDriverTableName(table_id); qfs::Query q(sql_conn); if(rec.isEmpty()) { if(serial_ix >= 0) { qs = "INSERT INTO %1 DEFAULT VALUES"; qs = qs.arg(table); } } else { qs = sqldrv->sqlStatement(QSqlDriver::InsertStatement, table, rec, true); //qs = fixSerialDefaultValue(qs, serial_ix, rec); } if(qs.isEmpty()) continue; qfDebug() << "\texecuting prepared query:" << qs; bool ok = q.prepare(qs); if(!ok) { qfError() << "Cannot prepare query:" << qs; } else { for(int i=0; i<rec.count(); i++) { QVariant::Type type = rec.field(i).value().type(); //qfInfo() << "\t" << rec.field(i).name() << "bound type:" << QVariant::typeToName(type); qfDebug() << "\t\t" << rec.field(i).name() << "bound type:" << QVariant::typeToName(type) << "value:" << rec.field(i).value().toString().mid(0, 100); q.addBindValue(rec.field(i).value()); } } ok = q.exec(); if(ok) { qfDebug() << "\tnum rows affected:" << q.numRowsAffected(); int num_rows_affected = q.numRowsAffected(); //setNumRowsAffected(q.numRowsAffected()); QF_ASSERT(num_rows_affected == 1, tr("numRowsAffected() = %1, should be 1\n%2").arg(num_rows_affected).arg(qs), return false); if(serial_ix >= 0 && !serial_ix_explicitly_set) { QVariant v = q.lastInsertId(); qfDebug() << "\tsetting serial index:" << serial_ix << "to generated value:" << v; if(v.isValid()) { row_ref.setValue(serial_ix, v); row_ref.setDirty(serial_ix, false); } else { qfWarning() << "Serial field will not be initialized properly. This can make current transaction aborted."; } } if(primary_ix >= 0) { /// update foreign keys in the slave tables qf::core::utils::Table::Field pri_ix_fld = row_ref.fields().value(primary_ix); QString master_key = pri_ix_fld.name(); qfDebug() << "\t master_key:" << master_key; QString slave_key = m_foreignKeyDependencies.value(master_key); if(!slave_key.isEmpty()) { qfDebug() << "\tsetting value of foreign key" << slave_key << "to value of master key:" << row_ref.value(master_key).toString(); row_ref.setValue(slave_key, row_ref.value(master_key)); } } } else { QString errs = tr("Error executing query: %1\n %2").arg(qs).arg(q.lastError().text()); if(throw_exc) QF_EXCEPTION(errs); else qfError() << errs; } }
void tableTemplateWidget::savePrivateData(void) { int lastId = 0, cc = 0; crossInfo *cross; QSqlQuery query, query2; QSqlError le; query.prepare("DELETE FROM crossword.private_data WHERE _template = ?;"); query.addBindValue(QVariant(templateId)); query.exec(); le = query.lastError(); if (le.type() == QSqlError::NoError) { query.prepare("DELETE FROM crossword.crosses WHERE _template = ?;"); query.addBindValue(QVariant(templateId)); query.exec(); le = query.lastError(); if (le.type() != QSqlError::NoError) qDebug() << "2. savePrivateData: " << le.text(); } else qDebug() << "1. savePrivateData: " << le.text(); QVariantList tmp; QVariantList pdid; QVariantList cpos; QVariantList ctype; QVariantList nw; QSqlDriver *drv = db->driver(); drv->beginTransaction(); for (int i = 0; i < wi.count(); i++) { query.prepare("INSERT INTO crossword.private_data (_template, _numword, " "_row, _column, _lenght, _crosscount, _orientation) " "VALUES (?, ?, ?, ?, ?, ?, ?);"); query.addBindValue(QVariant(templateId)); query.addBindValue(QVariant(wi[i]->numWord)); query.addBindValue(QVariant(wi[i]->row)); query.addBindValue(QVariant(wi[i]->col)); query.addBindValue(QVariant(wi[i]->length)); query.addBindValue(QVariant(wi[i]->crossCount)); query.addBindValue(QVariant(wi[i]->orient)); query.exec(); le = query.lastError(); if (le.type() == QSqlError::NoError) { lastId = query.lastInsertId().toInt(); query2.prepare("INSERT INTO crossword.crosses (_template, _pd_id, _cpos, " "_ctype, _numword) VALUES (?, ?, ?, ?, ?);"); cc = wi[i]->crossCount; for (int j = 0; j < cc; j++) { cross = wi[i]->cil[j]; tmp << templateId; pdid << lastId; cpos << cross->crossPos; ctype << cross->crossType; nw << cross->numWord2; } query2.addBindValue(tmp); query2.addBindValue(pdid); query2.addBindValue(cpos); query2.addBindValue(ctype); query2.addBindValue(nw); query2.execBatch(QSqlQuery::ValuesAsRows); tmp.clear(); pdid.clear(); cpos.clear(); ctype.clear(); nw.clear(); } else qDebug() << "3. savePrivateData: " << le.text(); } drv->commitTransaction(); }
int main(int argc, char *argv[]) { if(argc <= 2) { QString arg = "-h"; if(argc > 1) arg = argv[1]; if(arg == QStringLiteral("-h") || arg == QStringLiteral("--help")) { std::cout << argv[0] << " FUSE_options --dbfs DBFS_options" << std::endl; std::cout << "FUSE_options" << std::endl; std::cout << "\tuse -h --dbfs switch to print FUSE options" << std::endl; std::cout << "DBFS_options" << std::endl; std::cout << "\t--dbfs\t" << "DBFS options separator, all options prior this will be ignored by DBFS" << std::endl; std::cout << "\t--host <host>\t" << "Database host" << std::endl; std::cout << "\t--port <port>\t" << "Database port" << std::endl; std::cout << "\t -u" << std::endl; std::cout << "\t--user <user>\t" << "Database user" << std::endl; std::cout << "\t -p" << std::endl; std::cout << "\t--password [<password>]\t" << "Database user password, use -p without password for interactive input." << std::endl; std::cout << "\t--database <database>\t" << "Database name" << std::endl; std::cout << "\t--db-schema\t" << "Database schema name" << std::endl; std::cout << "\t--table-name\t" << "DBFS table name, default is 'dbfs'" << std::endl; std::cout << "\t--create\t" << "Create DBFS tables" << std::endl; exit(0); } } int dbfs_switch_index; for(dbfs_switch_index = 1; dbfs_switch_index < argc; dbfs_switch_index++) if(argv[dbfs_switch_index] == QLatin1String("--dbfs")) { break; } QScopedPointer<qf::core::LogDevice> file_log_device(qf::core::FileLogDevice::install()); file_log_device->setDomainTresholds(argc - dbfs_switch_index, argv + dbfs_switch_index); file_log_device->setPrettyDomain(true); QString o_database; QString o_user; QString o_password; QString o_host; int o_port = 0; QString o_db_schema; QString o_table_name; bool o_create_db = false; bool o_ask_passwd = false; for(int i=dbfs_switch_index + 1; i<argc; i++) { QString arg = argv[i]; if(arg == QStringLiteral("--host")) { if(i<argc-1) { i++; o_host = argv[i]; } } else if(arg == QStringLiteral("--port")) { if(i<argc-1) { i++; o_port = QString(argv[i]).toInt(); } } else if(arg == QStringLiteral("-u") || arg == QStringLiteral("--user")) { if(i<argc-1) { i++; o_user = argv[i]; } } else if(arg == QStringLiteral("-p") || arg == QStringLiteral("--password")) { if(i<argc-1) { QString p = argv[i+1]; if(p.startsWith('-')) { o_ask_passwd = true; } else { o_password = p; i++; } } else { o_ask_passwd = true; } } else if(arg == QStringLiteral("--database")) { if(i<argc-1) { i++; o_database = argv[i]; } } else if(arg == QStringLiteral("--db-schema")) { if(i<argc-1) { i++; o_db_schema = argv[i]; } } else if(arg == QStringLiteral("--table-name")) { if(i<argc-1) { i++; o_table_name = argv[i]; } } else if(arg == QStringLiteral("--create")) { o_create_db = true; } } if(o_ask_passwd) { char pwd[256]; std::cout << "Please, enter your password: "******"Empty database name."; exit(1); } qfs::DbFsDriver *dbfs_drv = nullptr; qf::core::sql::Connection db_connection; if(dbfs_switch_index < (argc - 1)) { db_connection = QSqlDatabase::addDatabase("QPSQL"); db_connection.setHostName(o_host); if(o_port > 0) db_connection.setPort(o_port); db_connection.setDatabaseName(o_database); db_connection.setUserName(o_user); db_connection.setPassword(o_password); //qfInfo() << o_host << o_port << o_user << o_database; bool ok = db_connection.open(); if(!ok) { qfError() << db_connection.lastError().text(); exit(1); } if(!o_db_schema.isEmpty()) { if(!db_connection.setCurrentSchema(o_db_schema)) { qfError() << "Error setting db schema to:" << o_db_schema; exit(1); } } dbfs_drv = new qfs::DbFsDriver(); dbfs_drv->setConnectionName(db_connection.connectionName()); if(!o_table_name.isEmpty()) { dbfs_drv->setTableName(o_table_name); } if(o_create_db) { if(!dbfs_drv->createDbFs()) { qfError() << "Error creating dbfs table" << dbfs_drv->tableName(); } exit(1); } qfsqldbfs_setdriver(dbfs_drv); } int fuse_argc = dbfs_switch_index; /// FUSE variables struct fuse_args fuse_arguments = FUSE_ARGS_INIT(fuse_argc, argv); struct fuse_chan *fuse_channel = NULL; struct fuse *fuse_handle = NULL; char *mount_point = nullptr; if (fuse_parse_cmdline(&fuse_arguments, &mount_point, NULL, NULL) == -1) { qfError() << "fuse_parse_cmdline() - Error parsing fuse command line arguments!"; exit(1); } /// Tell FUSE where the local mountpoint is fuse_channel = fuse_mount(mount_point, &fuse_arguments); if (fuse_channel == NULL){ qfError()<<"fuse_mount() failed"; exit(1); } // Tell FUSE about implementations of FS operations struct fuse_operations fuse_ops; memset(&fuse_ops, 0, sizeof(fuse_ops)); fuse_ops.getattr = qfsqldbfs_getattr; fuse_ops.readdir = qfsqldbfs_readdir; fuse_ops.open = qfsqldbfs_open; fuse_ops.read = qfsqldbfs_read; fuse_ops.write = qfsqldbfs_write; fuse_ops.fsync = qfsqldbfs_fsync; fuse_ops.flush = qfsqldbfs_flush; fuse_ops.release = qfsqldbfs_release; fuse_ops.mknod = qfsqldbfs_mknod; fuse_ops.mkdir = qfsqldbfs_mkdir; fuse_ops.unlink = qfsqldbfs_unlink; fuse_ops.rmdir = qfsqldbfs_rmdir; fuse_ops.utime = qfsqldbfs_utime; fuse_ops.truncate = qfsqldbfs_truncate; fuse_ops.ftruncate = qfsqldbfs_ftruncate; fuse_ops.chmod = qfsqldbfs_chmod; fuse_ops.chown = qfsqldbfs_chown; fuse_ops.create = qfsqldbfs_create; fuse_ops.rename = qfsqldbfs_rename; fuse_handle = fuse_new(fuse_channel, &fuse_arguments, &fuse_ops, sizeof(fuse_ops), NULL); if (fuse_handle == NULL){ qfError()<<"fuse_new() failed"; exit(1); } if(dbfs_drv) { #ifdef USE_QT_EVENT_LOOP qfInfo() << "Using Qt event loop with FUSE in separated thread"; TheApp *app = new TheApp(argc, argv); s_fuseThread = new FuseThread(fuse_handle, fuse_channel, QString::fromUtf8(mount_point)); dbfs_drv->moveToThread(s_fuseThread); QObject::connect(s_fuseThread, &QThread::finished, app, &TheApp::onFuseThreadFinished, Qt::QueuedConnection); s_fuseThread->start(); set_signal_handlers(); { /// setup SQL notify QSqlDatabase notify_db = QSqlDatabase::addDatabase("QPSQL", "DBFS_Notify"); notify_db.setHostName(db_connection.hostName()); notify_db.setPort(db_connection.port()); notify_db.setUserName(db_connection.userName()); notify_db.setPassword(db_connection.password()); notify_db.setDatabaseName(db_connection.databaseName()); bool ok = notify_db.open(); if(!ok) { qfError() << "Error connect DBFS notify connection" << notify_db.lastError().text(); } else { QSqlDriver *drv = notify_db.driver(); //qRegisterMetaType<QSqlDriver::NotificationSource>("QSqlDriver::NotificationSource"); QObject::connect(drv, SIGNAL(notification(QString,QSqlDriver::NotificationSource,QVariant)), dbfs_drv, SLOT(onSqlNotify(QString,QSqlDriver::NotificationSource,QVariant)), Qt::DirectConnection); //QObject::connect(drv, SIGNAL(notification(QString,QSqlDriver::NotificationSource,QVariant)), app, SLOT(onSqlNotify(QString,QSqlDriver::NotificationSource,QVariant))); drv->subscribeToNotification(qfs::DbFsDriver::CHANNEL_INVALIDATE_DBFS_DRIVER_CACHE); qfInfo() << drv << "subscribedToNotifications:" << drv->subscribedToNotifications().join(", "); } } app->exec(); qfInfo() << "Waiting for FUSE thread to join ..."; s_fuseThread->wait(); #else qfInfo() << "Using FUSE event loop"; fuse_loop(fuse_handle); qfInfo() << "FUSE has quit its event loop"; #endif qfsqldbfs_setdriver(nullptr); QF_SAFE_DELETE(dbfs_drv); #ifdef USE_QT_EVENT_LOOP QF_SAFE_DELETE(s_fuseThread); QF_SAFE_DELETE(app); #endif } else { // used just to print FUSE help fuse_loop(fuse_handle); } qfInfo() << "bye"; return 0; }