📄 qsql_ibase.cpp
字号:
QSqlError::StatementError)) return QVariant(); unsigned short len = 0; QByteArray ba; int chunkSize = QIBaseChunkSize; ba.resize(chunkSize); int read = 0; while (isc_get_segment(status, &handle, &len, chunkSize, ba.data() + read) == 0 || status[1] == isc_segment) { read += len; ba.resize(read + chunkSize); } ba.resize(read); bool isErr = (status[1] == isc_segstr_eof ? false : isError(QT_TRANSLATE_NOOP("QIBaseResult", "Unable to read BLOB"), QSqlError::StatementError)); isc_close_blob(status, &handle); if (isErr) return QVariant(); ba.resize(read); return ba;}template<typename T>static QList<QVariant> toList(char** buf, int count, T* = 0){ QList<QVariant> res; for (int i = 0; i < count; ++i) { res.append(*(T*)(*buf)); *buf += sizeof(T); } return res;}/* char** ? seems like bad influence from oracle ... */template<>static QList<QVariant> toList<long>(char** buf, int count, long*){ QList<QVariant> res; for (int i = 0; i < count; ++i) { if (sizeof(int) == sizeof(long)) res.append(int((*(long*)(*buf)))); else res.append((qint64)(*(long*)(*buf))); *buf += sizeof(long); } return res;}static char* readArrayBuffer(QList<QVariant>& list, char *buffer, short curDim, short* numElements, ISC_ARRAY_DESC *arrayDesc, QTextCodec *tc){ const short dim = arrayDesc->array_desc_dimensions - 1; const unsigned char dataType = arrayDesc->array_desc_dtype; QList<QVariant> valList; unsigned short strLen = arrayDesc->array_desc_length; if (curDim != dim) { for(int i = 0; i < numElements[curDim]; ++i) buffer = readArrayBuffer(list, buffer, curDim + 1, numElements, arrayDesc, tc); } else { switch(dataType) { case blr_varying: case blr_varying2: strLen += 2; // for the two terminating null values case blr_text: case blr_text2: { int o; for (int i = 0; i < numElements[dim]; ++i) { for(o = 0; o < strLen && buffer[o]!=0; ++o ); if (tc) valList.append(tc->toUnicode(buffer, o)); else valList.append(QString::fromUtf8(buffer, o)); buffer += strLen; } break; } case blr_long: valList = toList<long>(&buffer, numElements[dim], static_cast<long *>(0)); break; case blr_short: valList = toList<short>(&buffer, numElements[dim]); break; case blr_int64: valList = toList<qint64>(&buffer, numElements[dim]); break; case blr_float: valList = toList<float>(&buffer, numElements[dim]); break; case blr_double: valList = toList<double>(&buffer, numElements[dim]); break; case blr_timestamp: for(int i = 0; i < numElements[dim]; ++i) { valList.append(fromTimeStamp(buffer)); buffer += sizeof(ISC_TIMESTAMP); } break; case blr_sql_time: for(int i = 0; i < numElements[dim]; ++i) { valList.append(fromTime(buffer)); buffer += sizeof(ISC_TIME); } break; case blr_sql_date: for(int i = 0; i < numElements[dim]; ++i) { valList.append(fromDate(buffer)); buffer += sizeof(ISC_DATE); } break; } } if (dim > 0) list.append(valList); else list += valList; return buffer;}QVariant QIBaseResultPrivate::fetchArray(int pos, ISC_QUAD *arr){ QList<QVariant> list; ISC_ARRAY_DESC desc; if (!arr) return list; QByteArray relname(sqlda->sqlvar[pos].relname, sqlda->sqlvar[pos].relname_length); QByteArray sqlname(sqlda->sqlvar[pos].aliasname, sqlda->sqlvar[pos].aliasname_length); isc_array_lookup_bounds(status, &ibase, &trans, relname.data(), sqlname.data(), &desc); if (isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not find array"), QSqlError::StatementError)) return list; int arraySize = 1, subArraySize; short dimensions = desc.array_desc_dimensions; short *numElements = new short[dimensions]; for(int i = 0; i < dimensions; ++i) { subArraySize = (desc.array_desc_bounds[i].array_bound_upper - desc.array_desc_bounds[i].array_bound_lower + 1); numElements[i] = subArraySize; arraySize = subArraySize * arraySize; } ISC_LONG bufLen; QByteArray ba; /* varying arrayelements are stored with 2 trailing null bytes indicating the length of the string */ if (desc.array_desc_dtype == blr_varying || desc.array_desc_dtype == blr_varying2) { desc.array_desc_length += 2; bufLen = desc.array_desc_length * arraySize * sizeof(short); } else { bufLen = desc.array_desc_length * arraySize; } ba.resize(int(bufLen)); isc_array_get_slice(status, &ibase, &trans, arr, &desc, ba.data(), &bufLen); if (isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not get array data"), QSqlError::StatementError)) return list; readArrayBuffer(list, ba.data(), 0, numElements, &desc, tc); delete[] numElements; return QVariant(list);}template<typename T>static char* fillList(char *buffer, const QList<QVariant> &list, T* = 0){ for (int i = 0; i < list.size(); ++i) { T val; val = qvariant_cast<T>(list.at(i)); memcpy(buffer, &val, sizeof(T)); buffer += sizeof(T); } return buffer;}template<>static char* fillList<float>(char *buffer, const QList<QVariant> &list, float*){ for (int i = 0; i < list.size(); ++i) { double val; float val2 = 0; val = qvariant_cast<double>(list.at(i)); val2 = (float)val; memcpy(buffer, &val2, sizeof(float)); buffer += sizeof(float); } return buffer;}static char* qFillBufferWithString(char *buffer, const QString& string, short buflen, bool varying, bool array, QTextCodec *tc){ QByteArray str = encodeString(tc, string); // keep a copy of the string alive in this scope if (varying) { short tmpBuflen = buflen; if (str.length() < buflen) buflen = str.length(); if (array) { // interbase stores varying arrayelements different than normal varying elements memcpy(buffer, str.data(), buflen); memset(buffer + buflen, 0, tmpBuflen - buflen); } else { *(short*)buffer = buflen; // first two bytes is the length memcpy(buffer + sizeof(short), str.data(), buflen); } buffer += tmpBuflen; } else { str = str.leftJustified(buflen, ' ', true); memcpy(buffer, str.data(), buflen); buffer += buflen; } return buffer;}static char* createArrayBuffer(char *buffer, const QList<QVariant> &list, QVariant::Type type, short curDim, ISC_ARRAY_DESC *arrayDesc, QString& error, QTextCodec *tc){ int i; ISC_ARRAY_BOUND *bounds = arrayDesc->array_desc_bounds; short dim = arrayDesc->array_desc_dimensions - 1; int elements = (bounds[curDim].array_bound_upper - bounds[curDim].array_bound_lower + 1); if (list.size() != elements) { // size mismatch error = QLatin1String("Expected size: %1. Supplied size: %2"); error = QLatin1String("Array size mismatch. Fieldname: %1 ") + error.arg(elements).arg(list.size()); return 0; } if (curDim != dim) { for(i = 0; i < list.size(); ++i) { if (list.at(i).type() != QVariant::List) { // dimensions mismatch error = QLatin1String("Array dimensons mismatch. Fieldname: %1"); return 0; } buffer = createArrayBuffer(buffer, list.at(i).toList(), type, curDim + 1, arrayDesc, error, tc); if (!buffer) return 0; } } else { switch(type) { case QVariant::Int: case QVariant::UInt: if (arrayDesc->array_desc_dtype == blr_short) buffer = fillList<short>(buffer, list); else buffer = fillList<int>(buffer, list); break; case QVariant::Double: if (arrayDesc->array_desc_dtype == blr_float) buffer = fillList<float>(buffer, list, static_cast<float *>(0)); else buffer = fillList<double>(buffer, list); break; case QVariant::LongLong: buffer = fillList<qint64>(buffer, list); break; case QVariant::ULongLong: buffer = fillList<quint64>(buffer, list); break; case QVariant::String: for (i = 0; i < list.size(); ++i) buffer = qFillBufferWithString(buffer, list.at(i).toString(), arrayDesc->array_desc_length, arrayDesc->array_desc_dtype == blr_varying, true, tc); break; case QVariant::Date: for (i = 0; i < list.size(); ++i) { *((ISC_DATE*)buffer) = toDate(list.at(i).toDate()); buffer += sizeof(ISC_DATE); } break; case QVariant::Time: for (i = 0; i < list.size(); ++i) { *((ISC_TIME*)buffer) = toTime(list.at(i).toTime()); buffer += sizeof(ISC_TIME); } break; case QVariant::DateTime: for (i = 0; i < list.size(); ++i) { *((ISC_TIMESTAMP*)buffer) = toTimeStamp(list.at(i).toDateTime()); buffer += sizeof(ISC_TIMESTAMP); } break; default: break; } } return buffer;}bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list){ QString error; ISC_QUAD *arrayId = (ISC_QUAD*) inda->sqlvar[column].sqldata; ISC_ARRAY_DESC desc; QByteArray relname(inda->sqlvar[column].relname, inda->sqlvar[column].relname_length); QByteArray sqlname(inda->sqlvar[column].aliasname, inda->sqlvar[column].aliasname_length); isc_array_lookup_bounds(status, &ibase, &trans, relname.data(), sqlname.data(), &desc); if (isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not find array"), QSqlError::StatementError)) return false; short arraySize = 1; ISC_LONG bufLen; QList<QVariant> subList = list; short dimensions = desc.array_desc_dimensions; for(int i = 0; i < dimensions; ++i) { arraySize *= (desc.array_desc_bounds[i].array_bound_upper - desc.array_desc_bounds[i].array_bound_lower + 1); } /* varying arrayelements are stored with 2 trailing null bytes indicating the length of the string */ if (desc.array_desc_dtype == blr_varying || desc.array_desc_dtype == blr_varying2) desc.array_desc_length += 2; bufLen = desc.array_desc_length * arraySize; QByteArray ba; ba.resize(int(bufLen)); if (list.size() > arraySize) { error = QLatin1String("Array size missmatch: size of %1 is %2, size of provided list is %3"); error = error.arg(QLatin1String(sqlname)).arg(arraySize).arg(list.size()); q->setLastError(QSqlError(error, QLatin1String(""), QSqlError::StatementError)); return false; } if (!createArrayBuffer(ba.data(), list, qIBaseTypeName(desc.array_desc_dtype, inda->sqlvar[column].sqlscale < 0), 0, &desc, error, tc)) { q->setLastError(QSqlError(error.arg(QLatin1String(sqlname)), QLatin1String(""), QSqlError::StatementError)); return false; } /* readjust the buffer size*/ if (desc.array_desc_dtype == blr_varying || desc.array_desc_dtype == blr_varying2) desc.array_desc_length -= 2; isc_array_put_slice(status, &ibase, &trans, arrayId, &desc, ba.data(), &bufLen); return true;}bool QIBaseResultPrivate::isSelect(){ char acBuffer[9]; char qType = isc_info_sql_stmt_type; isc_dsql_sql_info(status, &stmt, 1, &qType, sizeof(acBuffer), acBuffer); if (isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not get query info"), QSqlError::StatementError)) return false; int iLength = isc_vax_integer(&acBuffer[1], 2); queryType = isc_vax_integer(&acBuffer[3], iLength); return (queryType == isc_info_sql_stmt_select || queryType == isc_info_sql_stmt_exec_procedure);}bool QIBaseResultPrivate::transaction()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -