예제 #1
0
QStringList Project::databaseFieldList( const QString &connection, const QString &table )
{
    DatabaseConnection *conn = databaseConnection( connection );
    if ( !conn )
	return QStringList();
    return conn->fields( table );
}
/**
 *
 * We received a disconnect signal. Lets cleanup the connection in question
 *
 * @param args The arguments passed from the database
 * @return void
 */
void DatabaseConnectionManager::disconnected(const VariantVector &args)
{
    DatabaseConnection *connection;
    std::string uuid;
    Variant uid = args.data()[0];

    uuid = uid.toString();

    // Find connection
    connection = disconnectingConnections[uuid];

    // Stop running
    connection->stop();

    // Wait for the connection to finish
    while (!connection->isFinished()) {

        // Process any pending events
        Application::getInstance()->processEvents();

        // Sleep for 30ms.
        usleep(30 * 1000);
    }

    // Remove from collection
    disconnectingConnections.erase(uuid);

    // Free memory
    if (connection != mainConnection) {
        delete connection;
    }
}
예제 #3
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
void
DatabaseService::onDestroy(wpDatabaseConnection_type _pConnection)
{
    Threading::CriticalSection lock(m_pConnectionsGuard);

    connections_types::iterator iter = m_namedConnections.find(_pConnection->getName());
    if (iter != m_namedConnections.end())
    {
        // This is safe since the only place that this can transition
        // from expired to non-expired is in connect() where m_pConnectionsGuard
        // is acquired.
        if (iter->second.expired())
        {
            m_namedConnections.erase(iter);

            DatabaseConnection* pConn = dynamic_cast<DatabaseConnection*>(_pConnection.get());

            pConn->onDestroyEvent(_pConnection);
            delete pConn;
        }
        else
        {
            // Not expired, so we are here for no reason
            // We can get here during race conditions where one shared_ptr
            // is being deleted while connect() is being called and connect()
            // beat onDestroy() to the lock(m_pConnectionsGuard).
            return;
        }
    }
    else
    {
        // TODO Severe error, should never get here
    }
}
예제 #4
0
QStringList Project::databaseConnectionList()
{
    QStringList lst;
    for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() )
	lst << conn->name();
    return lst;
}
예제 #5
0
void Database::run()
{

    m_initialized = dbInitialize();
	m_condition.notify_one();
	if(!m_initialized)
	{
		return;
	}
	

    Query* q;
    while (!m_shutdown)
    {
        m_queryQueue.popWait(q);
        
        if(m_shutdown && !q)
        {
            // no remaining connection, we can quit the thread
            return;
        }
        
        DatabaseConnection* dbc;
        m_dbConnQueue.popWait(dbc);
        dbc->processQuery(q);
    }
}
예제 #6
0
QStringList Project::databaseTableList( const QString &connection )
{
    DatabaseConnection *conn = databaseConnection( connection );
    if ( !conn ) {
	return QStringList();
    }
    return conn->tables();
}
예제 #7
0
bool Database::executeSynchronousQuery(Query* q)
{
	    DatabaseConnection* dbc;
        m_dbConnQueue.popWait(dbc);

		dbc->processSynchronousQuery(q);

		releaseDBConnection(dbc);
		return true;
}
예제 #8
0
DatabaseConnection *Project::databaseConnection( const QString &name )
{
    for ( DatabaseConnection *conn = dbConnections.first();
	  conn;
	  conn = dbConnections.next() ) {
	if ( conn->name() == name )
	    return conn;
    }
    return 0;
}
예제 #9
0
QPtrList<DesignerDatabase> DesignerProjectImpl::databaseConnections() const
{
    QPtrList<DesignerDatabase> lst;
#ifndef QT_NO_SQL
    QPtrList<DatabaseConnection> conns = project->databaseConnections();
    for ( DatabaseConnection *d = conns.first(); d; d = conns.next() )
	lst.append( d->iFace() );
#endif
    return lst;
}
예제 #10
0
void Project::removeDatabaseConnection( const QString &c )
{
    for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) {
	if ( conn->name() == c ) {
	    conn->remove();
	    dbConnections.removeRef( conn );
	    delete conn;
	    return;
	}
    }
}
예제 #11
0
/*! Closes the database \a connection.
*/
void Project::closeDatabase( const QString &connection )
{
#ifndef QT_NO_SQL
    DatabaseConnection *conn = databaseConnection( connection );
    if ( connection.isEmpty() && !conn )
	conn = databaseConnection( "(default)" );
    if ( !conn )
	return;
    conn->close();
#else
    Q_UNUSED( connection );
#endif
}
예제 #12
0
파일: database.cpp 프로젝트: fr33mind/SMTUC
void Database::addDatabase(Database * db)
{
    if (! db)
        return;

    QString connectionName = db->connectionName();
    if (mDatabaseConnections.contains(connectionName)) {
        DatabaseConnection* dbConnection = mDatabaseConnections.value(connectionName);
        dbConnection->addDatabase(db);
    }
    else {
        mDatabaseConnections.insert(connectionName, new DatabaseConnection(connectionName));
    }
}
예제 #13
0
SEXP dbConnect(SEXP dbType_sexp,
	       SEXP connection_string_sexp,
	       SEXP user_sexp,
	       SEXP pass_sexp,
	       SEXP host_sexp,
	       SEXP port_sexp,
	       SEXP tty_sexp,
	       SEXP dbName_sexp,
	       SEXP options_sexp) {

  SEXP dbi_conn_sexp;
  DatabaseConnection* conn = NULL;
  const char* dbType = CHAR(STRING_PTR(dbType_sexp)[0]);
  const char* connection_string = (connection_string_sexp == R_NilValue) ? NULL : CHAR(STRING_PTR(connection_string_sexp)[0]);
  const char* user = (user_sexp == R_NilValue) ? NULL : CHAR(STRING_PTR(user_sexp)[0]);
  const char* pass = (pass_sexp == R_NilValue) ? NULL : CHAR(STRING_PTR(pass_sexp)[0]);
  const char* host = (host_sexp == R_NilValue) ? NULL : CHAR(STRING_PTR(host_sexp)[0]);
  const char* port = (port_sexp == R_NilValue) ? NULL : CHAR(STRING_PTR(port_sexp)[0]);
  const char* tty = (tty_sexp == R_NilValue) ? NULL : CHAR(STRING_PTR(tty_sexp)[0]);
  const char* dbName = (dbName_sexp == R_NilValue) ? NULL : CHAR(STRING_PTR(dbName_sexp)[0]);
  const char* options = (options_sexp == R_NilValue) ? NULL : CHAR(STRING_PTR(options_sexp)[0]);

  // this test is to check whether the package was compiled with support
  // for this specific dbType
  try {
    conn = DatabaseConnection::init(dbType);
  } catch (DriverNotSupported& e) {
    REprintf("%s\n",e.what());
    return R_NilValue;
  }

  // if we succeed then return a wrapped connection, otherwise return null
  try {
    // if user provides connection_string, then use it, otherwise try traditional args
    if(connection_string) {
      conn->connect(connection_string);
    } else {
      conn->connect(user,pass,host,port,tty,dbName,options);
    }
  } catch(BadDatabaseConnection& e) {
    REprintf("%s\n",e.what());
    return R_NilValue;
  }

  PROTECT(dbi_conn_sexp = R_MakeExternalPtr(reinterpret_cast<void*>(conn),install("DBI_conn_pointer"),R_NilValue));
  R_RegisterCFinalizerEx(dbi_conn_sexp, connFinalizer, TRUE);
  UNPROTECT(1);
  return dbi_conn_sexp;
}
예제 #14
0
SEXP dbListTables(SEXP dbi_conn_sexp) {

 if(TYPEOF(dbi_conn_sexp) != EXTPTRSXP || dbi_conn_sexp == R_NilValue) {
    return R_NilValue;
  }

  DatabaseConnection* conn = reinterpret_cast<DatabaseConnection*>(R_ExternalPtrAddr(dbi_conn_sexp));
  if(!conn) {
    // throw bad_connection_object
    REprintf("bad database connection.\n");
    return R_NilValue;
  }

  return conn->listTables();
}
예제 #15
0
파일: database.cpp 프로젝트: fr33mind/SMTUC
void Database::removeDatabase(Database * db)
{
    if (! db)
        return;

    QString connectionName = db->connectionName();
    if (mDatabaseConnections.contains(connectionName)) {
        DatabaseConnection* dbConnection = mDatabaseConnections.value(connectionName);
        dbConnection->removeDatabase(db);
        if (! dbConnection->isActive()) {
            mDatabaseConnections.remove(connectionName);
            dbConnection->deleteLater();
        }
    }
}
예제 #16
0
bool Project::openDatabase( const QString &connection, bool suppressDialog )
{
#ifndef QT_NO_SQL
    DatabaseConnection *conn = databaseConnection( connection );
    if ( connection.isEmpty() && !conn )
	conn = databaseConnection( "(default)" );
    if ( !conn )
	return FALSE;
    bool b = conn->open( suppressDialog );
    return b;
#else
    Q_UNUSED( connection );
    Q_UNUSED( suppressDialog );
    return FALSE;
#endif
}
예제 #17
0
/**
 *
 * Destroys this connection manager
 *
 * @return void
 */
DatabaseConnectionManager::~DatabaseConnectionManager()
{
    DatabaseConnection *connection;
    bool waiting = true;

    while (waiting) {

        // Our default state is not waiting
        waiting = false;

        Connections connections(this->connections);
        for (Connections::const_iterator it = connections.begin();
                it != connections.end(); ++it) {

            connection = it->first;

            if (connection->isStopping()) {

                // Wait for the connection to finish
                connection->join();

                // Remove from collection
                this->connections.erase(connection);

                // Free memory
                if (connection != mainConnection) {
                    delete connection;
                }
            } else {

                // Ask the connection to stop running
                connection->stop(false);

                // This connection may not be finished yet
                waiting = true;
            }
        }
    }

    delete this->mainConnection;

    #ifdef TRACK_POINTERS
    rDebug << "DatabaseConnectionManager::destroy" << this;
    #endif
}
예제 #18
0
SEXP dbSendQuery(SEXP dbi_conn_sexp, SEXP qry_sexp) {
  if(TYPEOF(dbi_conn_sexp) != EXTPTRSXP || dbi_conn_sexp == R_NilValue) {
    return R_NilValue;
  }

  SEXP dbi_query_results_sexp;
  DatabaseConnection* conn = reinterpret_cast<DatabaseConnection*>(R_ExternalPtrAddr(dbi_conn_sexp));
  if(!conn) {
    // throw bad_connection_object
    return R_NilValue;
  }
  const char* qry = CHAR(STRING_PTR(qry_sexp)[0]);
  QueryResults* query_results = conn->sendQuery(qry);
  //query_results->getStatus();

  PROTECT(dbi_query_results_sexp = R_MakeExternalPtr(reinterpret_cast<void*>(query_results),install("DBI_results_pointer"),R_NilValue));
  R_RegisterCFinalizerEx(dbi_query_results_sexp, queryResultsFinalizer, TRUE);
  UNPROTECT(1);
  return dbi_query_results_sexp;
}
예제 #19
0
SEXP dbExistsTable(SEXP dbi_conn_sexp, SEXP tableName_sexp) {
  SEXP ans;

 if(TYPEOF(dbi_conn_sexp) != EXTPTRSXP || dbi_conn_sexp == R_NilValue) {
    return R_NilValue;
  }

  DatabaseConnection* conn = reinterpret_cast<DatabaseConnection*>(R_ExternalPtrAddr(dbi_conn_sexp));
  if(!conn) {
    // throw bad_connection_object
    REprintf("bad database connection.\n");
    return R_NilValue;
  }

  const char* tableName = CHAR(STRING_ELT(tableName_sexp,0));
  PROTECT(ans = allocVector(LGLSXP,1));
  LOGICAL(ans)[0] = static_cast<int>(conn->existsTable(tableName));
  UNPROTECT(1);
  return ans;
}
예제 #20
0
bool MysqlDatabase::dbInitialize()
{
   
		for (uint32 i=0; i < m_poolConnSize; i++)
		{
			DatabaseConnection* dbc = new MysqlDatabaseConnection(this,m_login,m_host,m_password,m_database,m_port);
			m_dbConnQueue.push(dbc);
			m_dbConn.push_back(dbc);
			
			if(!dbc->dbInitialize())
			{
				Logger::log("%s\n",dbc->error().c_str());
				return false;
			}
			m_group.create_thread(boost::bind(&MysqlDatabaseConnection::run, dbc));
		}

		return true;

}
예제 #21
0
// return number of rows written to database
// using both overwrite and append is a bad design decision
// there should just be overwrite, which will drop the table if it exists
// append should be automatic if the table exists, and should fail if the row formats don't match up
// having both overwrite and append just complicates the logic of this function
SEXP dbWriteTable(SEXP dbi_conn_sexp, SEXP tableName_sexp, SEXP value_sexp, SEXP writeRowNames_sexp, SEXP overWrite_sexp, SEXP append_sexp) {
  SEXP ans;
  int rows;

 if(TYPEOF(dbi_conn_sexp) != EXTPTRSXP || dbi_conn_sexp == R_NilValue) {
    return R_NilValue;
  }

  DatabaseConnection* conn = reinterpret_cast<DatabaseConnection*>(R_ExternalPtrAddr(dbi_conn_sexp));
  if(!conn) {
    // throw bad_connection_object
    REprintf("bad database connection.\n");
    return ScalarInteger(0);
  }
  if(TYPEOF(tableName_sexp) != STRSXP) {
    REprintf("ERROR: tableName is not a string.\n");
    return ScalarInteger(0);
  }
  const char* tableName = CHAR(STRING_ELT(tableName_sexp,0));
  const bool writeRowNames = static_cast<bool>(LOGICAL(writeRowNames_sexp)[0]);
  const bool overWrite = static_cast<bool>(LOGICAL(overWrite_sexp)[0]);

  if(conn->existsTable(tableName) && overWrite) {
    if(!conn->removeTable(tableName)) {
      REprintf("could not remove existing table (aborting).\n");
      return ScalarInteger(0);
    }
  }

  try {
    rows = conn->writeTable(tableName, value_sexp, writeRowNames);
  } catch (MapToTypeNotImplemented& e) {
    REprintf("%s\n",e.what());
    return R_NilValue;
  }
  PROTECT(ans = allocVector(INTSXP,1));
  INTEGER(ans)[0] = rows;
  UNPROTECT(1);
  return ans;
}
예제 #22
0
/*! This is a helper to filter out duplicate code from the GetXXXList functions.
    The name_type is assumed to be the name of the table, and the column in the table
    is assumed to be "<name_type>_name".*/
static bool NameList(const string& name_type, 
                     const DatabaseConnection& database,
                     vector<string>* list) {
  if (list == NULL) return false;
  Table results;
  if (!database.Query("SELECT * FROM get_" + name_type + "_names();", 
      &results)) return false;
  const int num_rows = results.NumRows();
  list->reserve(num_rows);
  int name_column;
  if (!results.GetColumnIndex(name_type + "_name", &name_column)) return false;
  string name;
  for (int row = 0; row < num_rows; ++row) {
    if (!results.GetField(name_column, row, &name)) return false;
    list->push_back(name);
  }
  return true;
}
예제 #23
0
void
do_speed_test()
{
    string const filename("aaksjh237nsal");
    int const loops = 50000;
    
    vector<string> statements;
    statements.push_back
    (   "insert into dummy(colA, colB) values(3, 'hi')"
    );
    statements.push_back
    (   "select colA, colB from dummy where colB = "
        " 'asfkjasdlfkasdfasdf' and colB = '-90982097';"
    );
    statements.push_back
    (   "insert into dummy(colA, colB) values(198712319, 'aasdfhasdkjhash');"
    );
    statements.push_back
    (   "select colA, colB from dummy where colA = "
        " 'noasdsjhasdfkjhasdkfjh' and colB = '-9987293879';"
    );

    vector<string>::size_type const num_statements = statements.size();

    string const table_creation_string
    (   "create table dummy(colA int not null, colB text)"
    );
    

    // With SQLStatement
    DatabaseConnection db;
    db.open(filename);
    db.execute_sql(table_creation_string);

    cout << "Timing with SQLStatement." << endl;
    db.execute_sql("begin");
    Stopwatch sw1;
    for (int i = 0; i != loops; ++i)
    {
        SQLStatement s(db, statements[i % num_statements]);
        // s.step_final();
    }
    sw1.log();
    db.execute_sql("end");
    windows_friendly_remove(filename);


    // With SQLStatementImpl
    SQLiteDBConn sdbc;
    sdbc.open(filename);
    sdbc.execute_sql(table_creation_string);

    cout << "Timing with SQLStatementImpl." << endl;
    sdbc.execute_sql("begin");
    Stopwatch sw0;
    for (int i = 0; i != loops; ++i)
    {
        SQLStatementImpl s(sdbc, statements[i % num_statements]);
        // s.step_final();
    }
    sw0.log();
    sdbc.execute_sql("end");
    windows_friendly_remove(filename);
    
    return;
}
예제 #24
0
/**
 *
 * Reserves a database connection. Until this is freed, it will not be re-used.
 *
 * @param timeout The minimum amount of time to use this connection in seconds
 * @param receiver The object which we'll send any data to
 *
 * @return A UUID for this connection
 */
DatabaseConnection *DatabaseConnectionManager::reserveDatabaseConnectionObj(
        int timeout, SmartObject *receiver)
{
    ConnectionRecord record, currentRecord;
    DatabaseConnection *connection = nullptr, *currentConnection;
    int count;
    bool running, busy;

    if (timeout != 0) {

        // Expiry = unixtime + whatever timeout started as
        timeout += std::time(nullptr);
    }

    while (connection == nullptr) {

        // Reset counter
        count = 0;

        // Iterate connections
        Connections connections(this->connections);
        for (Connections::iterator it = connections.begin();
             it != connections.end(); ++it) {

            currentConnection = it->first;
            currentRecord = it->second;

            if (currentRecord.expiry != 0) {

                // This connection has an expiry. No expiry indicates that it is
                // a reserved connection that should not be re-assigned.
                if (connection == nullptr) {

                    // Lock this connection's mutex
                    currentConnection->mutex.lock();

                    // Check if this connection is in the process of shutting
                    // down or is busy with something (or has pending queries)
                    busy = currentConnection->busy
                            || !currentConnection->commands.empty();

                    // Unlock the mutex
                    currentConnection->mutex.unlock();

                    if (currentConnection->isStopping() && !busy) {

                        // Re-use this connection
                        connection = currentConnection;

                        // Disconnect the execution signal so if the old
                        // receiver is still around it won't keep getting
                        // signals
                        connection->disconnectQueue(
                            DatabaseConnection::EXECUTED);

                        // Rollback transaction if applicable
                        connection->call(Variant(),
                                         QueryEvent::CLEAN_STATE);
                    }

                } else if (currentRecord.expiry != 0
                           && currentRecord.expiry > std::time(nullptr)) {

                    // This connection has expired

                    // Lock this connection's mutex
                    currentConnection->mutex.lock();

                    // Check if this connection is in the process of shutting
                    // down or is busy with something
                    busy = currentConnection->busy
                            || !currentConnection->commands.empty();

                    // Unlock the mutex
                    currentConnection->mutex.unlock();

                    if (!busy) {
                        // Tell the connection to disconnect. We'll free memory
                        // after that is finished
                        if (!currentConnection->isStopping()) {

                            // Ensure this connection's signals are disconnected
                            currentConnection->disconnectQueue(
                                DatabaseConnection::EXECUTED);

                            // Connect to ourself. After the disconnect
                            // completes, we need to free the connection

                            currentConnection->connectQueue(
                                DatabaseConnection::EXECUTED, this);

                            currentConnection->call(Variant(currentRecord.uuid),
                                QueryEvent::DISCONNECT);
                        }

                        // Remove from the hash
                        this->connections.erase(currentConnection);

                        // Add to the disconnections hash
                        disconnectingConnections[currentRecord.uuid]
                                = currentConnection;
                    }
                }

                count++;
            }
        }

        if (connection == nullptr && count < maxConnections) {

            // Initialize new connection
            connection = mainConnection->clone(this);

            // Start new thread
            connection->start();
        }

        if (connection != nullptr) {
            record.expiry = timeout;
            record.uuid = UUID::makeUUID();
            record.receiver = receiver;
            this->connections[connection] = record;
        }

        if (connection == nullptr) {
            // Process any pending events
            Application::getInstance()->processEvents();

            // Also sleep for 30ms. There may not be events to process above
            // and we don't want to pin the cpu
            usleep(30 * 1000);
        }
    }

    if (receiver != nullptr) {

        // Lock mutex
        connection->mutex.lock();

        // Connect signal
        connection->connectQueue(DatabaseConnection::EXECUTED, receiver);

        // Unlock mutex
        connection->mutex.unlock();
    }

    return connection;
}
예제 #25
0
int main() {
	DatabaseConnection db;
	try {
		db.execute(const_cast<char *>("SELECT * FROM test2;"));

		// Example: Listing all columns from executed query
		cout << "Lists all columns from table" << endl;

		list<string> columns = db.getColumns();
		for(list<string>::iterator i = columns.begin(); i != columns.end(); i++)
			cout << (*i) << endl;

		// Example: Extracting specific data types into acceptable data types
		cout << endl << "Extract specific data types" << endl;

		int intTest = db.getInt(const_cast<char *>("intTest"));
		double doubleTest = db.getDouble(const_cast<char *>("doubleTest"));
		int numericTest = db.getInt(const_cast<char *>("numericTest"));
		string blobTest = db.getText(const_cast<char *>("blobTest"));
		string textTest = db.getText(const_cast<char *>("textTest"));

		cout << "INT: " << intTest << endl;
		cout << "DOUBLE: " << doubleTest << endl;
		cout << "NUMERIC: " << numericTest << endl;
		cout << "BLOB: " << blobTest << endl;
		cout << "TEXT: " << textTest << endl;

		// Resets the pointer back to the beginning
		db.reset();

		// Example: Extract any type of data types
		cout << endl << "Extract any type of data types" << endl;
		cout << "NUMERICTEST: " << db.getColumn(const_cast<char *>("numericTest")) << " TEXTTEST: " << db.getColumn(const_cast<char *>("textTest")) << endl;

		// Got new set of data. Why? Because I can.
		db.finalize();
		db.execute(const_cast<char *>("SELECT * FROM test;"));

		// Example: Extract all data obtained from executing the query
		cout << endl << "Extract all data from query and store in a list of multimaps" << endl;
		list<multimap<string, string> > results = db.fetchAll();
		list<multimap<string, string> >::iterator rows = results.begin();

		while(rows != results.end()) {
			multimap<string, string>::iterator row = (*rows).begin();
			while(row != (*rows).end()) {
				cout << (*row).first << " " << (*row).second << " ";
				row++;
			}

			cout << endl;

			rows++;
		}
	} catch (DatabaseConnectionException e) {
		cout << e.getMessage();
	}

	// Deletes pointer to query
	db.finalize();

	// Deletes pointer to database connection
	db.close();

	return 0;
}
예제 #26
0
void Project::loadConnections()
{
#ifndef QT_NO_SQL
    if ( dbFile.isEmpty() || !QFile::exists( makeAbsolute( dbFile ) ) )
	return;

    QFile f( makeAbsolute( dbFile ) );
    if ( f.open( IO_ReadOnly ) ) {
	QDomDocument doc;
	QString errMsg;
	int errLine;
	if ( doc.setContent( &f, &errMsg, &errLine ) ) {
	    QDomElement e;
	    e = doc.firstChild().toElement();

	    /* connections */
	    QDomNodeList connections = e.toElement().elementsByTagName( "connection" );
	    for ( uint i = 0; i <  connections.length(); i++ ) {
		QDomElement connection = connections.item(i).toElement();
		QDomElement connectionName = loadSingleProperty( connection, "name" );
		QDomElement connectionDriver = loadSingleProperty( connection, "driver" );
		QDomElement connectionDatabase = loadSingleProperty( connection,
								     "database" );
		QDomElement connectionUsername = loadSingleProperty( connection,
								     "username" );
		QDomElement connectionHostname = loadSingleProperty( connection,
								     "hostname" );
		QDomElement connectionPort = loadSingleProperty( connection,
								     "port" );

		DatabaseConnection *conn = new DatabaseConnection( this );
		conn->setName( connectionName.firstChild().firstChild().toText().data() );
		conn->setDriver( connectionDriver.firstChild().firstChild().toText().data() );
		conn->setDatabase( connectionDatabase.firstChild().firstChild().toText().data() );
		conn->setUsername( connectionUsername.firstChild().firstChild().toText().data() );
		conn->setHostname( connectionHostname.firstChild().firstChild().toText().data() );
		conn->setPort( QString( connectionPort.firstChild().firstChild().toText().data() ).toInt() );

		/* connection tables */
		QDomNodeList tables = connection.toElement().elementsByTagName( "table" );
		for ( uint j = 0; j <  tables.length(); j++ ) {
		    QDomElement table = tables.item(j).toElement();
		    QDomElement tableName = loadSingleProperty( table, "name" );
		    conn->addTable( tableName.firstChild().firstChild().toText().data() );

		    /* table fields */
		    QStringList fieldList;
		    QDomNodeList fields = table.toElement().elementsByTagName( "field" );
		    for ( uint k = 0; k <  fields.length(); k++ ) {
			QDomElement field = fields.item(k).toElement();
			QDomElement fieldName = loadSingleProperty( field, "name" );
			fieldList.append( fieldName.firstChild().firstChild().toText().data() );
		    }
		    conn->setFields( tableName.firstChild().firstChild().toText().data(),
					 fieldList );
		}

		dbConnections.append( conn );
	    }
	} else {
	    qDebug( QString("Parse error: ") + errMsg + QString(" in line %d"), errLine );
	}
	f.close();
    }
#endif
}
예제 #27
0
void Project::saveConnections()
{
#ifndef QT_NO_SQL
    if ( dbFile.isEmpty() ) {
	QFileInfo fi( fileName() );
	setDatabaseDescription( fi.baseName() + ".db" );
    }

    QFile f( makeAbsolute( dbFile ) );

    if ( dbConnections.isEmpty() ) {
	if ( f.exists() )
	    f.remove();
	setDatabaseDescription( "" );
	modified = TRUE;
	return;
    }

    /* .db xml */
    if ( f.open( IO_WriteOnly | IO_Translate ) ) {
	QTextStream ts( &f );
	ts.setCodec( QTextCodec::codecForName( "UTF-8" ) );
	ts << "<!DOCTYPE DB><DB version=\"1.0\">" << endl;

	/* db connections */
	int indent = 0;
	for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) {
	    ts << makeIndent( indent ) << "<connection>" << endl;
	    ++indent;
	    saveSingleProperty( ts, "name", conn->name(), indent );
	    saveSingleProperty( ts, "driver", conn->driver(), indent );
	    saveSingleProperty( ts, "database", conn->database(), indent );
	    saveSingleProperty( ts, "username", conn->username(), indent );
	    saveSingleProperty( ts, "hostname", conn->hostname(), indent );
	    saveSingleProperty( ts, "port", QString::number( conn->port() ), indent );

	    /* connection tables */
	    QStringList tables = conn->tables();
	    for ( QStringList::Iterator it = tables.begin();
		  it != tables.end(); ++it ) {
		ts << makeIndent( indent ) << "<table>" << endl;
		++indent;
		saveSingleProperty( ts, "name", (*it), indent );

		/* tables fields */
		QStringList fields = conn->fields( *it );
		for ( QStringList::Iterator it2 = fields.begin();
		      it2 != fields.end(); ++it2 ) {
		    ts << makeIndent( indent ) << "<field>" << endl;
		    ++indent;
		    saveSingleProperty( ts, "name", (*it2), indent );
		    --indent;
		    ts << makeIndent( indent ) << "</field>" << endl;
		}

		--indent;
		ts << makeIndent( indent ) << "</table>" << endl;
	    }

	    --indent;
	    ts << makeIndent( indent ) << "</connection>" << endl;
	}

	ts << "</DB>" << endl;
	f.close();
    }
#endif
}