示例#1
1
	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());
	}
示例#2
1
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;
}
示例#3
1
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;
}
示例#4
1
	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 ) );
}
示例#6
0
	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;
}
示例#8
0
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);
}
示例#9
0
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");
    }
}
示例#10
0
	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;
	}
示例#11
0
	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;
	}
示例#12
0
	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();
	}
示例#13
0
	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;
	}
示例#14
0
/**
  * 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 );
}
示例#16
0
/*
 * Зберігаємо шаблон кросворду після редагування решітки
 */
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);
}
示例#17
0
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;
			}
		}
示例#18
0
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();
}
示例#19
0
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;
}