📄 qsql_ibase.cpp
字号:
return -1;#endif}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(QT_TRANSLATE_NOOP("QIBaseResult", "Could not get statement info"), QSqlError::StatementError)) 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;}QSqlRecord QIBaseResult::record() const{ QSqlRecord rec; if (!isActive() || !d->sqlda) return rec; XSQLVAR v; for (int i = 0; i < d->sqlda->sqld; ++i) { v = d->sqlda->sqlvar[i]; QSqlField f(QString::fromLatin1(v.aliasname, v.aliasname_length).simplified(), qIBaseTypeName2(d->sqlda->sqlvar[i].sqltype, v.sqlscale < 0)); f.setLength(v.sqllen); f.setPrecision(v.sqlscale); f.setSqlType(v.sqltype); f.setRequiredStatus(QSqlField::Unknown); rec.append(f); } return rec;}QVariant QIBaseResult::handle() const{ return QVariant(qRegisterMetaType<isc_stmt_handle>("isc_stmt_handle"), &d->stmt);}/*********************************/QIBaseDriver::QIBaseDriver(QObject * parent) : QSqlDriver(parent){ d = new QIBaseDriverPrivate(this);}QIBaseDriver::QIBaseDriver(isc_db_handle connection, QObject *parent) : QSqlDriver(parent){ d = new QIBaseDriverPrivate(this); d->ibase = connection; setOpen(true); setOpenError(false);}QIBaseDriver::~QIBaseDriver(){ delete d;}bool QIBaseDriver::hasFeature(DriverFeature f) const{ switch (f) { case QuerySize: case NamedPlaceholders: case LastInsertId: case BatchOperations: case SimpleLocking: case LowPrecisionNumbers: return false; case Transactions: case PreparedQueries: case PositionalPlaceholders: case Unicode: case BLOB: return true; } 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(); const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts)); QString encString; QByteArray role; for (int i = 0; i < opts.count(); ++i) { QString tmp(opts.at(i).simplified()); int idx; if ((idx = tmp.indexOf(QLatin1Char('='))) != -1) { QString val = tmp.mid(idx + 1).simplified(); QString opt = tmp.left(idx).simplified(); if (opt.toUpper() == QLatin1String("ISC_DPB_LC_CTYPE")) encString = val; else if (opt.toUpper() == QLatin1String("ISC_DPB_SQL_ROLE_NAME")) { role = val.toLocal8Bit(); role.truncate(255); } } } // Use UNICODE_FSS when no ISC_DPB_LC_CTYPE is provided if (encString.isEmpty()) encString = QLatin1String("UNICODE_FSS"); else { d->tc = QTextCodec::codecForName(encString.toLocal8Bit()); if (!d->tc) { qWarning("Unsupported encoding: %s. Using UNICODE_FFS for ISC_DPB_LC_CTYPE.", encString.toLocal8Bit().constData()); encString = QLatin1String("UNICODE_FSS"); // Fallback to UNICODE_FSS } } QByteArray enc = encString.toLocal8Bit(); QByteArray usr = user.toLocal8Bit(); QByteArray pass = password.toLocal8Bit(); enc.truncate(255); usr.truncate(255); pass.truncate(255); QByteArray ba; ba.resize(usr.length() + pass.length() + enc.length() + role.length() + 6); int i = -1; ba[++i] = isc_dpb_version1; ba[++i] = isc_dpb_user_name; ba[++i] = usr.length(); memcpy(ba.data() + ++i, usr.data(), usr.length()); i += usr.length(); ba[i] = isc_dpb_password; ba[++i] = pass.length(); memcpy(ba.data() + ++i, pass.data(), pass.length()); i += pass.length(); ba[i] = isc_dpb_lc_ctype; ba[++i] = enc.length(); memcpy(ba.data() + ++i, enc.data(), enc.length()); i += enc.length(); if (!role.isEmpty()) { ba[i] = isc_dpb_sql_role_name; ba[++i] = role.length(); memcpy(ba.data() + ++i, role.data(), role.length()); i += role.length(); } QString ldb; if (!host.isEmpty()) ldb += host + QLatin1Char(':'); ldb += db; isc_attach_database(d->status, 0, const_cast<char *>(ldb.toLatin1().constData()), &d->ibase, i, ba.data()); if (d->isError(QT_TRANSLATE_NOOP("QIBaseDriver", "Error opening database"), QSqlError::ConnectionError)) { 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); }}QSqlResult *QIBaseDriver::createResult() const{ return 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(QT_TRANSLATE_NOOP("QIBaseDriver", "Could not start transaction"), QSqlError::TransactionError);}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(QT_TRANSLATE_NOOP("QIBaseDriver", "Unable to commit transaction"), QSqlError::TransactionError);}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(QT_TRANSLATE_NOOP("QIBaseDriver", "Unable to rollback transaction"), QSqlError::TransactionError);}QStringList QIBaseDriver::tables(QSql::TableType type) const{ QStringList res; if (!isOpen()) return res; QString typeFilter; if (type == QSql::SystemTables) { typeFilter += QLatin1String("RDB$SYSTEM_FLAG != 0"); } else if (type == (QSql::SystemTables | QSql::Views)) { typeFilter += QLatin1String("RDB$SYSTEM_FLAG != 0 OR RDB$VIEW_BLR NOT NULL"); } else { if (!(type & QSql::SystemTables)) typeFilter += QLatin1String("RDB$SYSTEM_FLAG = 0 AND "); if (!(type & QSql::Views)) typeFilter += QLatin1String("RDB$VIEW_BLR IS NULL AND "); if (!(type & QSql::Tables)) typeFilter += QLatin1String("RDB$VIEW_BLR IS NOT NULL AND "); if (!typeFilter.isEmpty()) typeFilter.chop(5); } if (!typeFilter.isEmpty()) typeFilter.prepend(QLatin1String("where ")); QSqlQuery q(createResult()); q.setForwardOnly(true); if (!q.exec(QLatin1String("select rdb$relation_name from rdb$relations ") + typeFilter)) return res; while(q.next()) res << q.value(0).toString().simplified(); return res;}QSqlRecord QIBaseDriver::record(const QString& tablename) const{ QSqlRecord rec; if (!isOpen()) return rec; QSqlQuery q(createResult()); q.setForwardOnly(true); q.exec(QLatin1String("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.toUpper() + QLatin1String("' " "ORDER BY a.RDB$FIELD_POSITION")); while (q.next()) { int type = q.value(1).toInt(); bool hasScale = q.value(3).toInt() < 0; QSqlField f(q.value(0).toString().simplified(), qIBaseTypeName(type, hasScale)); f.setLength(q.value(2).toInt()); f.setPrecision(q.value(4).toInt()); f.setRequired(q.value(5).toInt() > 0 ? true : false); f.setSqlType(type); rec.append(f); } return rec;}QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const{ QSqlIndex index(table); if (!isOpen()) return index; QSqlQuery q(createResult()); q.setForwardOnly(true); q.exec(QLatin1String("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE, d.RDB$FIELD_SCALE " "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.toUpper() + QLatin1String(" '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().simplified(), qIBaseTypeName(q.value(2).toInt(), q.value(3).toInt() < 0)); index.append(field); //TODO: asc? desc? index.setName(q.value(0).toString()); } return index;}QString QIBaseDriver::formatValue(const QSqlField &field, bool trimStrings) const{ switch (field.type()) { case QVariant::DateTime: { QDateTime datetime = field.value().toDateTime(); if (datetime.isValid()) return QLatin1Char('\'') + QString::number(datetime.date().year()) + QLatin1Char('-') + QString::number(datetime.date().month()) + QLatin1Char('-') + QString::number(datetime.date().day()) + QLatin1Char(' ') + QString::number(datetime.time().hour()) + QLatin1Char(':') + QString::number(datetime.time().minute()) + QLatin1Char(':') + QString::number(datetime.time().second()) + QLatin1Char('.') + QString::number(datetime.time().msec()).rightJustified(3, QLatin1Char('0'), true) + QLatin1Char('\''); else return QLatin1String("NULL"); } case QVariant::Time: { QTime time = field.value().toTime(); if (time.isValid()) return QLatin1Char('\'') + QString::number(time.hour()) + QLatin1Char(':') + QString::number(time.minute()) + QLatin1Char(':') + QString::number(time.second()) + QLatin1Char('.') + QString::number(time.msec()).rightJustified(3, QLatin1Char('0'), true) + QLatin1Char('\''); else return QLatin1String("NULL"); } case QVariant::Date: { QDate date = field.value().toDate(); if (date.isValid()) return QLatin1Char('\'') + QString::number(date.year()) + QLatin1Char('-') + QString::number(date.month()) + QLatin1Char('-') + QString::number(date.day()) + QLatin1Char('\''); else return QLatin1String("NULL"); } default: return QSqlDriver::formatValue(field, trimStrings); }}QVariant QIBaseDriver::handle() const{ return QVariant(qRegisterMetaType<isc_db_handle>("isc_db_handle"), &d->ibase);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -