⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qsql_psql.cpp

📁 Linux下的基于X11的图形开发环境。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
PGconn* QPSQLDriver::connection(){    return d->connection;}bool QPSQLDriver::hasFeature( DriverFeature f ) const{    switch ( f ) {    case Transactions:	return TRUE;    case QuerySize:	return TRUE;    case BLOB:	return FALSE;    case Unicode:	return d->isUtf8;    default:	return FALSE;    }}static QPSQLDriver::Protocol getPSQLVersion( PGconn* connection ){    PGresult* result = PQexec( connection, "select version()" );    int status =  PQresultStatus( result );    if ( status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK ) {	QString val( PQgetvalue( result, 0, 0 ) );	PQclear( result );	QRegExp rx( "(\\d*)\\.(\\d*)" );	rx.setMinimal ( TRUE ); // enforce non-greedy RegExp        if ( rx.search( val ) != -1 ) {	    int vMaj = rx.cap( 1 ).toInt();	    int vMin = rx.cap( 2 ).toInt();	    if ( vMaj < 6 ) {#ifdef QT_CHECK_RANGE		qWarning( "This version of PostgreSQL is not supported and may not work." );#endif		return QPSQLDriver::Version6;	    }	    if ( vMaj == 6 ) {		return QPSQLDriver::Version6;	    }	    if ( vMaj == 7 ) {		if ( vMin < 1 ) {		    return QPSQLDriver::Version7;		} else {		    return QPSQLDriver::Version71;		}	    }	    if ( vMaj > 7 ) {		return QPSQLDriver::Version71;	    }	}    } else {#ifdef QT_CHECK_RANGE	qWarning( "This version of PostgreSQL is not supported and may not work." );#endif    }    return QPSQLDriver::Version6;}bool QPSQLDriver::open( const QString & db,			const QString & user,			const QString & password,			const QString & host,			int port ){    int status;    if ( isOpen() )	close();    QString connectString;    if ( host.length() )	connectString.append( "host=" ).append( host );    if ( db.length() )	connectString.append( " dbname=" ).append( db );    if ( user.length() )	connectString.append( " user=" ).append( user );    if ( password.length() )	connectString.append( " password=" ).append( password );    if ( port > -1 )	connectString.append( " port=" ).append( QString::number( port ) );    d->connection = PQconnectdb( connectString.local8Bit().data() );    if ( PQstatus( d->connection ) == CONNECTION_BAD ) {	setLastError( qMakeError("Unable to connect", QSqlError::Connection, d ) );	setOpenError( TRUE );	return FALSE;    }// Unicode support is only working if the client library has been compiled with// multibyte support.#ifdef MULTIBYTE    status = PQsetClientEncoding( d->connection, "UNICODE" );    if ( status == 0 ) {	d->isUtf8 = TRUE;    }#endif    pro = getPSQLVersion( d->connection );    PGresult* dateResult = 0;    switch( pro ) {    case QPSQLDriver::Version6:	dateResult = PQexec( d->connection, "SET DATESTYLE TO 'ISO'" );	break;    case QPSQLDriver::Version7:    case QPSQLDriver::Version71:	dateResult = PQexec( d->connection, "SET DATESTYLE=ISO" );	break;    }#ifdef QT_CHECK_RANGE    status =  PQresultStatus( dateResult );    if ( status != PGRES_COMMAND_OK )	qWarning( PQerrorMessage( d->connection ) );#endif    setOpen( TRUE );    return TRUE;}void QPSQLDriver::close(){    if ( isOpen() ) {	PQfinish( d->connection );	d->connection = 0;	setOpen( FALSE );	setOpenError( FALSE );    }}QSqlQuery QPSQLDriver::createQuery() const{    return QSqlQuery( new QPSQLResult( this, d ) );}bool QPSQLDriver::beginTransaction(){    if ( !isOpen() ) {#ifdef QT_CHECK_RANGE	qWarning( "QPSQLDriver::beginTransaction: Database not open" );#endif	return FALSE;    }    PGresult* res = PQexec( d->connection, "BEGIN" );    if ( !res || PQresultStatus( res ) != PGRES_COMMAND_OK ) {	PQclear( res );	setLastError( qMakeError( "Could not begin transaction", QSqlError::Transaction, d ) );	return FALSE;    }    PQclear( res );    return TRUE;}bool QPSQLDriver::commitTransaction(){    if ( !isOpen() ) {#ifdef QT_CHECK_RANGE	qWarning( "QPSQLDriver::commitTransaction: Database not open" );#endif	return FALSE;    }    PGresult* res = PQexec( d->connection, "COMMIT" );    if ( !res || PQresultStatus( res ) != PGRES_COMMAND_OK ) {	PQclear( res );	setLastError( qMakeError( "Could not commit transaction", QSqlError::Transaction, d ) );	return FALSE;    }    PQclear( res );    return TRUE;}bool QPSQLDriver::rollbackTransaction(){    if ( !isOpen() ) {#ifdef QT_CHECK_RANGE	qWarning( "QPSQLDriver::rollbackTransaction: Database not open" );#endif	return FALSE;    }    PGresult* res = PQexec( d->connection, "ROLLBACK" );    if ( !res || PQresultStatus( res ) != PGRES_COMMAND_OK ) {	setLastError( qMakeError( "Could not rollback transaction", QSqlError::Transaction, d ) );	PQclear( res );	return FALSE;    }    PQclear( res );    return TRUE;}QStringList QPSQLDriver::tables( const QString& /* user */ ) const{    QStringList tl;    if ( !isOpen() )	return tl;    QSqlQuery t = createQuery();    QString stmt;    stmt = "select relname from pg_class where ( relkind = 'r' or relkind = 'v' ) "		"and ( relname !~ '^Inv' ) "		"and ( relname !~ '^pg_' ) ";    t.exec( stmt );    while ( t.isActive() && t.next() )	tl.append( t.value(0).toString() );    return tl;}QSqlIndex QPSQLDriver::primaryIndex( const QString& tablename ) const{    QSqlIndex idx( tablename );    if ( !isOpen() )	return idx;    QSqlQuery i = createQuery();    QString stmt;    switch( pro ) {    case QPSQLDriver::Version6:	stmt = "select pg_att1.attname, int(pg_att1.atttypid), pg_att2.attnum, pg_cl.relname "		"from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind "		"where pg_cl.relname = '%1_pkey' AND pg_cl.oid = pg_ind.indexrelid "		"and pg_att2.attrelid = pg_ind.indexrelid "		"and pg_att1.attrelid = pg_ind.indrelid "		"and pg_att1.attnum = pg_ind.indkey[pg_att2.attnum-1] "		"order by pg_att2.attnum";	break;    case QPSQLDriver::Version7:    case QPSQLDriver::Version71:	stmt = "select pg_att1.attname, pg_att1.atttypid::int, pg_cl.relname "		"from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind "		"where pg_cl.relname = '%1_pkey' AND pg_cl.oid = pg_ind.indexrelid "		"and pg_att2.attrelid = pg_ind.indexrelid "		"and pg_att1.attrelid = pg_ind.indrelid "		"and pg_att1.attnum = pg_ind.indkey[pg_att2.attnum-1] "		"order by pg_att2.attnum";	break;    }    i.exec( stmt.arg( tablename ) );    while ( i.isActive() && i.next() ) {	QSqlField f( i.value(0).toString(), qDecodePSQLType( i.value(1).toInt() ) );	idx.append( f );	idx.setName( i.value(2).toString() );    }    return idx;}QSqlRecord QPSQLDriver::record( const QString& tablename ) const{    QSqlRecord fil;    if ( !isOpen() )	return fil;    QString stmt;    switch( pro ) {    case QPSQLDriver::Version6:	stmt = "select pg_attribute.attname, int(pg_attribute.atttypid) "			"from pg_class, pg_attribute "			"where pg_class.relname = '%1' "			"and pg_attribute.attnum > 0 "			"and pg_attribute.attrelid = pg_class.oid ";	break;    case QPSQLDriver::Version7:    case QPSQLDriver::Version71:	stmt = "select pg_attribute.attname, pg_attribute.atttypid::int "			"from pg_class, pg_attribute "			"where pg_class.relname = '%1' "			"and pg_attribute.attnum > 0 "			"and pg_attribute.attrelid = pg_class.oid ";	break;    }    QSqlQuery fi = createQuery();    fi.exec( stmt.arg( tablename ) );    while ( fi.next() ) {	QSqlField f( fi.value(0).toString(), qDecodePSQLType( fi.value(1).toInt() ) );	fil.append( f );    }    return fil;}QSqlRecord QPSQLDriver::record( const QSqlQuery& query ) const{    QSqlRecord fil;    if ( !isOpen() )	return fil;    if ( query.isActive() && query.driver() == this ) {	QPSQLResult* result = (QPSQLResult*)query.result();	int count = PQnfields( result->d->result );	for ( int i = 0; i < count; ++i ) {	    QString name = PQfname( result->d->result, i );	    QVariant::Type type = qDecodePSQLType( PQftype( result->d->result, i ) );	    QSqlField rf( name, type );	    fil.append( rf );	}    }    return fil;}QSqlRecordInfo QPSQLDriver::recordInfo( const QString& tablename ) const{    QSqlRecordInfo info;    if ( !isOpen() )	return info;    QString stmt;    switch( pro ) {    case QPSQLDriver::Version6:	stmt = "select pg_attribute.attname, int(pg_attribute.atttypid), pg_attribute.attnotnull, "		"pg_attribute.attlen, pg_attribute.atttypmod, int(pg_attribute.attrelid), pg_attribute.attnum "		"from pg_class, pg_attribute "		"where pg_class.relname = '%1' "		"and pg_attribute.attnum > 0 "		"and pg_attribute.attrelid = pg_class.oid ";	break;    case QPSQLDriver::Version7:	stmt = "select pg_attribute.attname, pg_attribute.atttypid::int, pg_attribute.attnotnull, "		"pg_attribute.attlen, pg_attribute.atttypmod, pg_attribute.attrelid::int, pg_attribute.attnum "		"from pg_class, pg_attribute "		"where pg_class.relname = '%1' "		"and pg_attribute.attnum > 0 "		"and pg_attribute.attrelid = pg_class.oid ";	break;    case QPSQLDriver::Version71:	stmt = "select pg_attribute.attname, pg_attribute.atttypid::int, pg_attribute.attnotnull, "		"pg_attribute.attlen, pg_attribute.atttypmod, pg_attrdef.adsrc "		"from pg_class, pg_attribute "		"left join pg_attrdef on (pg_attrdef.adrelid = pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "		"where pg_class.relname = '%1' "		"and pg_attribute.attnum > 0 "		"and pg_attribute.attrelid = pg_class.oid ";	break;    }    QSqlQuery query = createQuery();    query.exec( stmt.arg( tablename ) );    if ( pro == QPSQLDriver::Version71 ) {	while ( query.next() ) {	    int len = query.value( 3 ).toInt();	    int precision = query.value( 4 ).toInt();	    // swap length and precision if length == -1	    if ( len == -1 && precision > -1 ) {		len = precision - 4;		precision = -1;	    }	    QString defVal = query.value( 5 ).toString();	    if ( !defVal.isEmpty() && defVal.startsWith( "'" ) )		defVal = defVal.mid( 1, defVal.length() - 2 );	    info.append( QSqlFieldInfo( query.value( 0 ).toString(),					qDecodePSQLType( query.value( 1 ).toInt() ),					query.value( 2 ).toBool(),					len,					precision,					defVal,					query.value( 1 ).toInt() ) );	}    } else {	// Postgres < 7.1 cannot handle outer joins	while ( query.next() ) {	    QString defVal;	    QString stmt2 = "select pg_attrdef.adsrc from pg_attrdef where "			    "pg_attrdef.adrelid = %1 and pg_attrdef.adnum = %2 ";	    QSqlQuery query2 = createQuery();	    query2.exec( stmt2.arg( query.value( 5 ).toInt() ).arg( query.value( 6 ).toInt() ) );	    if ( query2.isActive() && query2.next() )		defVal = query2.value( 0 ).toString();	    if ( !defVal.isEmpty() && defVal.startsWith( "'" ) )		defVal = defVal.mid( 1, defVal.length() - 2 );	    int len = query.value( 3 ).toInt();	    int precision = query.value( 4 ).toInt();	    // swap length and precision if length == -1	    if ( len == -1 && precision > -1 ) {		len = precision - 4;		precision = -1;	    }	    info.append( QSqlFieldInfo( query.value( 0 ).toString(),					qDecodePSQLType( query.value( 1 ).toInt() ),					query.value( 2 ).toBool(),					len,					precision,					defVal,					query.value( 1 ).toInt() ) );	}    }    return info;}QSqlRecordInfo QPSQLDriver::recordInfo( const QSqlQuery& query ) const{    QSqlRecordInfo info;    if ( !isOpen() )	return info;    if ( query.isActive() && query.driver() == this ) {	QPSQLResult* result = (QPSQLResult*)query.result();	int count = PQnfields( result->d->result );	for ( int i = 0; i < count; ++i ) {	    QString name = PQfname( result->d->result, i );	    int len = PQfsize( result->d->result, i );	    int precision = PQfmod( result->d->result, i );	    // swap length and precision if length == -1	    if ( len == -1 && precision > -1 ) {		len = precision - 4;		precision = -1;	    }	    info.append( QSqlFieldInfo( name,					qDecodePSQLType( PQftype( result->d->result, i ) ),					-1,					len,					precision,					QVariant(),					PQftype( result->d->result, i ) ) );	}    }    return info;}QString QPSQLDriver::formatValue( const QSqlField* field,				  bool ) const{    QString r;    if ( field->isNull() ) {	r = nullText();    } else {	switch ( field->type() ) {	case QVariant::DateTime:	    if ( field->value().toDateTime().isValid() ) {		QDate dt = field->value().toDateTime().date();		QTime tm = field->value().toDateTime().time();		// msecs need to be right aligned otherwise psql		// interpretes them wrong		r = "'" + QString::number( dt.year() ) + "-" +			  QString::number( dt.month() ) + "-" +			  QString::number( dt.day() ) + " " +			  tm.toString() + "." +			  QString::number( tm.msec() ).rightJustify( 3, '0' ) + "'";	    } else {		r = nullText();	    }	    break;	case QVariant::Time:	    if ( field->value().toTime().isValid() ) {		r = field->value().toTime().toString( Qt::ISODate );	    } else {		r = nullText();	    }	case QVariant::String:	case QVariant::CString: {	    // Escape '\' characters	    r = QSqlDriver::formatValue( field );	    r.replace( "\\", "\\\\" );	    break;	}	case QVariant::Bool:	    if ( field->value().toBool() )		r = "TRUE";	    else		r = "FALSE";	    break;	case QVariant::ByteArray:#ifdef QT_CHECKRANGE	    // bytearrays cannot be inserted directly into postgresql	    qWarning( "QPSQLDriver::formatValue: cannot format ByteArray." );#endif	    break;	case QVariant::Rect: {	    QRect rec = field->value().toRect();	    // upper right corner then lower left according to psql docs	    r = "'(" + QString::number( rec.right() ) +		"," + QString::number( rec.bottom() ) +		"),(" + QString::number( rec.left() ) +		"," + QString::number( rec.top() ) + ")'";	    break;	}	case QVariant::Point: {	    QPoint p = field->value().toPoint();	    r = "'(" + QString::number( p.x() ) +	        "," + QString::number( p.y() ) + ")'";	    break;	}	case QVariant::PointArray: {	    QPointArray pa = field->value().toPointArray();	    r = "' ";	    for ( int i = 0; i < (int)pa.size(); ++i ) {		r += "(" + QString::number( pa[i].x() ) +		     "," + QString::number( pa[i].y() ) + "),";	    }	    r.truncate( r.length() - 1 );	    r += "'";	    break;	}	default:	    r = QSqlDriver::formatValue( field );	    break;	}    }    return r;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -