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

📄 qsql_ibase.cpp

📁 Trolltech公司发布的基于C++图形开发环境
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	    }	}    }    if (colCount()) {	isc_dsql_free_statement(d->status, &d->stmt, DSQL_close);	if (d->isError("Unable to close statement"))	    return FALSE;	cleanup();    }    if (d->sqlda)	init(d->sqlda->sqld);    isc_dsql_execute2(d->status, &d->trans, &d->stmt, 1, d->inda, 0);    if (d->isError("Unable to execute query"))	return FALSE;    setActive(TRUE);    return TRUE;}bool QIBaseResult::reset (const QString& query){//    qDebug("reset: %s", query.ascii());    if (!driver() || !driver()->isOpen() || driver()->isOpenError())	return FALSE;    d->cleanup();    setActive(FALSE);    setAt(QSql::BeforeFirst);        createDA(d->sqlda);    if (!d->transaction())	return FALSE;        isc_dsql_allocate_statement(d->status, &d->ibase, &d->stmt);    if (d->isError("Could not allocate statement", QSqlError::Statement))	return FALSE;    isc_dsql_prepare(d->status, &d->trans, &d->stmt, 0, query.utf8().data(), 3, d->sqlda);    if (d->isError("Could not prepare statement", QSqlError::Statement))	return FALSE;        if (d->sqlda->sqld > d->sqlda->sqln) {	// need more field descriptors	int n = d->sqlda->sqld;	free(d->sqlda);	d->sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(n));	d->sqlda->sqln = n;	d->sqlda->version = SQLDA_VERSION1;	isc_dsql_describe(d->status, &d->stmt, 1, d->sqlda);	if (d->isError("Could not describe statement", QSqlError::Statement))	    return FALSE;    }        initDA(d->sqlda);    setSelect(d->isSelect());    if (isSelect()) {	init(d->sqlda->sqld);    } else {	free(d->sqlda);	d->sqlda = 0;    }        isc_dsql_execute(d->status, &d->trans, &d->stmt, 1, 0);    if (d->isError("Unable to execute query"))	return FALSE;    // commit non-select queries (if they are local)    if (!isSelect() && !d->commit())	return FALSE;        setActive(TRUE);    return TRUE;}bool QIBaseResult::gotoNext(QtSqlCachedResult::RowCache* row){    ISC_STATUS stat = isc_dsql_fetch(d->status, &d->stmt, 1, d->sqlda);        if (stat == 100) {	// no more rows	setAt(QSql::AfterLast);	return FALSE;    }    if (d->isError("Could not fetch next item", QSqlError::Statement))	return FALSE;    if (!row) // not interested in actual values	return TRUE;    Q_ASSERT(row);    Q_ASSERT((int)row->size() == d->sqlda->sqld);    for (int i = 0; i < d->sqlda->sqld; ++i) {	char *buf = d->sqlda->sqlvar[i].sqldata;	int size = d->sqlda->sqlvar[i].sqllen;	Q_ASSERT(buf);		if ((d->sqlda->sqlvar[i].sqltype & 1) && *d->sqlda->sqlvar[i].sqlind) {	    // null value	    QVariant v;	    v.cast(qIBaseTypeName2(d->sqlda->sqlvar[i].sqltype));	    (*row)[i] = v;	    continue;	}    	switch(d->sqlda->sqlvar[i].sqltype & ~1) {	case SQL_VARYING:	    // pascal strings - a short with a length information followed by the data	    (*row)[i] = QString::fromUtf8(buf + sizeof(short), *(short*)buf);	    break;	case SQL_INT64:	    if (d->sqlda->sqlvar[i].sqlscale < 0)		(*row)[i] = *(Q_LLONG*)buf * pow(10, d->sqlda->sqlvar[i].sqlscale);	    else		(*row)[i] = QVariant(*(Q_LLONG*)buf);	    break;	case SQL_LONG:	    if (sizeof(int) == sizeof(long)) //dear compiler: please optimize me out.		(*row)[i] = QVariant((int)(*(long*)buf));	    else		(*row)[i] = QVariant((Q_LLONG)(*(long*)buf));	    break;	case SQL_SHORT:	    (*row)[i] = QVariant((int)(*(short*)buf));	    break;	case SQL_FLOAT:	    (*row)[i] = QVariant((double)(*(float*)buf));	    	    break;	case SQL_DOUBLE:	    (*row)[i] = QVariant(*(double*)buf);	    break;	case SQL_TIMESTAMP:	    (*row)[i] = toQDateTime((ISC_TIMESTAMP*)buf);            break;	case SQL_TYPE_TIME:	    (*row)[i] = toQTime(*(ISC_TIME*)buf);	    break;        case SQL_TYPE_DATE:	    (*row)[i] = toQDate(*(ISC_DATE*)buf);            break;	case SQL_TEXT:	    (*row)[i] = QString::fromUtf8(buf, size);	    break;	case SQL_BLOB:	    (*row)[i] = d->fetchBlob((ISC_QUAD*)buf);	    break;	default:	    // unknown type - don't even try to fetch	    (*row)[i] = QVariant();	    break;	}	    }    return TRUE;    }int QIBaseResult::size(){    static char sizeInfo[] = {isc_info_sql_records};    char buf[33];        if (!isActive() || !isSelect())	return -1;        isc_dsql_sql_info(d->status, &d->stmt, sizeof(sizeInfo), sizeInfo, sizeof(buf), buf);    for (char* c = buf + 3; *c != isc_info_end; /*nothing*/) {	char ct = *c++;	short len = isc_vax_integer(c, 2);	c += 2;	int val = isc_vax_integer(c, len);	c += len;	if (ct == isc_info_req_select_count)	    return val;    }    return -1;}int QIBaseResult::numRowsAffected(){    static char acCountInfo[] = {isc_info_sql_records};    char cCountType;    switch (d->queryType) {    case isc_info_sql_stmt_select:	cCountType = isc_info_req_select_count;	break;    case isc_info_sql_stmt_update:	cCountType = isc_info_req_update_count;	break;    case isc_info_sql_stmt_delete:	cCountType = isc_info_req_delete_count;	break;    case isc_info_sql_stmt_insert:	cCountType = isc_info_req_insert_count;	break;    }    char acBuffer[33];    int iResult = -1;        isc_dsql_sql_info(d->status, &d->stmt, sizeof(acCountInfo), acCountInfo, sizeof(acBuffer), acBuffer);    if (d->isError("Could not get statement info", QSqlError::Statement))	return -1;    for (char *pcBuf = acBuffer + 3; *pcBuf != isc_info_end; /*nothing*/) {	char cType = *pcBuf++;	short sLength = isc_vax_integer (pcBuf, 2);	pcBuf += 2;	int iValue = isc_vax_integer (pcBuf, sLength);	pcBuf += sLength;			if (cType == cCountType) {	    iResult = iValue;	    break;	}    }    return iResult;    }/*********************************/QIBaseDriver::QIBaseDriver(QObject * parent, const char * name)    : QSqlDriver(parent, name ? name : QIBASE_DRIVER_NAME){    d = new QIBaseDriverPrivate(this);}QIBaseDriver::QIBaseDriver(void *connection, QObject *parent, const char *name)    : QSqlDriver(parent, name ? name : QIBASE_DRIVER_NAME){    d = new QIBaseDriverPrivate(this);    d->ibase = (isc_db_handle)connection;    setOpen(TRUE);    setOpenError(FALSE);}QIBaseDriver::~QIBaseDriver(){    delete d;}bool QIBaseDriver::hasFeature(DriverFeature f) const{    switch (f) {    case Transactions://    case QuerySize:    case PreparedQueries:    case PositionalPlaceholders:    case Unicode:    case BLOB:        return TRUE;    default:        return FALSE;    }}bool QIBaseDriver::open(const QString & db,	  const QString & user,	  const QString & password,	  const QString & host,	  int /*port*/,	  const QString & /* connOpts */){    if (isOpen())        close();        static const char enc[8] = "UTF_FSS";    QCString usr = user.local8Bit();    QCString pass = password.local8Bit();    usr.truncate(255);    pass.truncate(255);    QByteArray ba(usr.length() + pass.length() + sizeof(enc) + 6);    int i = -1;    ba[++i] = isc_dpb_version1;    ba[++i] = isc_dpb_user_name;    ba[++i] = usr.length();    memcpy(&ba[++i], usr.data(), usr.length());    i += usr.length();    ba[i] = isc_dpb_password;    ba[++i] = pass.length();    memcpy(&ba[++i], pass.data(), pass.length());    i += pass.length();    ba[i] = isc_dpb_lc_ctype;    ba[++i] = sizeof(enc) - 1;    memcpy(&ba[++i], enc, sizeof(enc) - 1);    i += sizeof(enc) - 1;    QString ldb;    if (!host.isEmpty())	ldb += host + ":";    ldb += db;    isc_attach_database(d->status, 0, (char*)ldb.latin1(), &d->ibase, i, ba.data());    if (d->isError("Error opening database", QSqlError::Connection)) {	setOpenError(TRUE);	return FALSE;    }        setOpen(TRUE);    return TRUE;}void QIBaseDriver::close(){    if (isOpen()) {	isc_detach_database(d->status, &d->ibase);	d->ibase = 0;	setOpen(FALSE);	setOpenError(FALSE);    }}QSqlQuery QIBaseDriver::createQuery() const{    return QSqlQuery(new QIBaseResult(this));}bool QIBaseDriver::beginTransaction(){    if (!isOpen() || isOpenError())	return FALSE;    if (d->trans)	return FALSE;        isc_start_transaction(d->status, &d->trans, 1, &d->ibase, 0, NULL);        return !d->isError("Could not start transaction", QSqlError::Transaction);}bool QIBaseDriver::commitTransaction(){    if (!isOpen() || isOpenError())	return FALSE;    if (!d->trans)	return FALSE;    isc_commit_transaction(d->status, &d->trans);    d->trans = 0;    return !d->isError("Unable to commit transaction", QSqlError::Transaction);}bool QIBaseDriver::rollbackTransaction(){    if (!isOpen() || isOpenError())	return FALSE;    if (!d->trans)	return FALSE;        isc_rollback_transaction(d->status, &d->trans);    d->trans = 0;    return !d->isError("Unable to rollback transaction", QSqlError::Transaction);}QStringList QIBaseDriver::tables(const QString& typeName) const{    QStringList res;    if (!isOpen())	return res;    int type = typeName.isEmpty() ? (int)QSql::Tables | (int)QSql::Views : typeName.toInt();    QString typeFilter;    if (type == (int)QSql::SystemTables) {	typeFilter += "RDB$SYSTEM_FLAG != 0";    } else if (type == ((int)QSql::SystemTables | (int)QSql::Views)) {	typeFilter += "RDB$SYSTEM_FLAG != 0 OR RDB$VIEW_BLR NOT NULL";    } else {	if (!(type & (int)QSql::SystemTables))	    typeFilter += "RDB$SYSTEM_FLAG = 0 AND ";	if (!(type & (int)QSql::Views))	    typeFilter += "RDB$VIEW_BLR IS NULL AND ";	if (!(type & (int)QSql::Tables))	    typeFilter += "RDB$VIEW_BLR IS NOT NULL AND ";	if (!typeFilter.isEmpty())	    typeFilter.truncate(typeFilter.length() - 5);    }    if (!typeFilter.isEmpty())	typeFilter.prepend("where ");        QSqlQuery q = createQuery();    q.setForwardOnly(TRUE);    if (!q.exec("select rdb$relation_name from rdb$relations " + typeFilter))	return res;    while(q.next())	    res << q.value(0).toString().stripWhiteSpace();    return res;}QSqlRecord QIBaseDriver::record(const QString& tablename) const{    QSqlRecord rec;    if (!isOpen())	return rec;	    QSqlQuery q = createQuery();    q.setForwardOnly(TRUE);        q.exec("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE "	   "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "	   "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE "	   "AND a.RDB$RELATION_NAME = '" + tablename.upper()+ "' "	   "ORDER BY RDB$FIELD_POSITION");    while (q.next()) {	QSqlField field(q.value(0).toString().stripWhiteSpace(), qIBaseTypeName(q.value(1).toInt()));	rec.append(field);   }    return rec;}QSqlRecordInfo QIBaseDriver::recordInfo(const QString& tablename) const{    QSqlRecordInfo rec;    if (!isOpen())	return rec;	    QSqlQuery q = createQuery();    q.setForwardOnly(TRUE);    q.exec("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, b.RDB$FIELD_SCALE, "	   "b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG "	   "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "	   "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE "	   "AND a.RDB$RELATION_NAME = '" + tablename.upper() + "' "	   "ORDER BY a.RDB$FIELD_POSITION");    while (q.next()) {	QVariant::Type type = qIBaseTypeName(q.value(1).toInt());	QSqlFieldInfo field(q.value(0).toString().stripWhiteSpace(), type, q.value(5).toInt(),			     q.value(2).toInt(), q.value(4).toInt(), QVariant());			rec.append(field);    }    return rec;}QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const{    QSqlIndex index(table);    if (!isOpen())	return index;    QSqlQuery q = createQuery();    q.setForwardOnly(TRUE);    q.exec("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE "	   "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d "	   "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' "	   "AND a.RDB$RELATION_NAME = '" + table.upper() + "' "	   "AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME "	   "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME "	   "AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME "	   "AND d.RDB$FIELD_NAME = c.RDB$FIELD_SOURCE "	   "ORDER BY b.RDB$FIELD_POSITION");    while (q.next()) {	QSqlField field(q.value(1).toString().stripWhiteSpace(), qIBaseTypeName(q.value(2).toInt()));	index.append(field); //TODO: asc? desc?	index.setName(q.value(0).toString());    }    return index;}QSqlRecord QIBaseDriver::record(const QSqlQuery& query) const{    QSqlRecord rec;    if (query.isActive() && query.driver() == this) {	QIBaseResult* result = (QIBaseResult*)query.result();	if (!result->d->sqlda)	    return rec;	XSQLVAR v;	for (int i = 0; i < result->d->sqlda->sqld; ++i) {	    v = result->d->sqlda->sqlvar[i];	    QSqlField f(QString::fromLatin1(v.sqlname, v.sqlname_length).stripWhiteSpace(),			qIBaseTypeName2(result->d->sqlda->sqlvar[i].sqltype));	    rec.append(f);	}    }    return rec;}QSqlRecordInfo QIBaseDriver::recordInfo(const QSqlQuery& query) const{    QSqlRecordInfo rec;    if (query.isActive() && query.driver() == this) {	QIBaseResult* result = (QIBaseResult*)query.result();	if (!result->d->sqlda)	    return rec;	XSQLVAR v;	for (int i = 0; i < result->d->sqlda->sqld; ++i) {	    v = result->d->sqlda->sqlvar[i];	    QSqlFieldInfo f(QString::fromLatin1(v.sqlname, v.sqlname_length).stripWhiteSpace(), 			    qIBaseTypeName2(result->d->sqlda->sqlvar[i].sqltype),			    -1, v.sqllen, QABS(v.sqlscale), QVariant(), v.sqltype);	    rec.append(f);	}    }    return rec;}QString QIBaseDriver::formatValue(const QSqlField* field, bool trimStrings) const{    switch (field->type()) {    case QVariant::DateTime: {	QDateTime datetime = field->value().toDateTime();	if (datetime.isValid())	    return "'" + QString::number(datetime.date().year()) + "-" +		QString::number(datetime.date().month()) + "-" +		QString::number(datetime.date().day()) + " " +		QString::number(datetime.time().hour()) + ":" +		QString::number(datetime.time().minute()) + ":" +		QString::number(datetime.time().second()) + "." +		QString::number(datetime.time().msec()).rightJustify(3, '0', TRUE) + "'";	else	    return "NULL";    }    case QVariant::Time: {	QTime time = field->value().toTime();	if (time.isValid())	    return "'" + QString::number(time.hour()) + ":" +		QString::number(time.minute()) + ":" +		QString::number(time.second()) + "." +		QString::number(time.msec()).rightJustify(3, '0', TRUE) + "'";	else	    return "NULL";    }    case QVariant::Date: {	QDate date = field->value().toDate();	if (date.isValid())	    return "'" + QString::number(date.year()) + "-" +		QString::number(date.month()) + "-" +		QString::number(date.day()) + "'";	    else		return "NULL";    }    default:        return QSqlDriver::formatValue(field, trimStrings);    }	}

⌨️ 快捷键说明

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