Beispiel #1
0
// This isn't going to work right now as it uses d->mysqlrow
QVariant MysqlCursor::value(int pos)
{
    if (!d->mysqlrow || pos >= m_fieldCount || d->mysqlrow[pos] == 0)
        return QVariant();

    KDbField *f = (m_visibleFieldsExpanded && pos < m_visibleFieldsExpanded->count())
                       ? m_visibleFieldsExpanded->at(pos)->field() : nullptr;

//! @todo js: use MYSQL_FIELD::type here!

    bool ok;
    return KDb::cstringToVariant(d->mysqlrow[pos], f ? f->type() : KDbField::Text,
                                            &ok, d->lengths[pos]);
}
void KexiDataSourcePage::slotFieldSelected()
{
    KDbField::Type dataType = KDbField::InvalidType;
#ifdef KEXI_AUTOFIELD_FORM_WIDGET_SUPPORT
    //! @todo this should also work for expressions
        KDbField *field = m_fieldListView->schema()->field(
                                   m_widgetDataSourceCombo->fieldOrExpression());
#else
    KDbField *field = m_tableOrQuerySchema->field(
                               m_widgetDataSourceCombo->fieldOrExpression());  //temp
#endif
    if (field)
        dataType = field->type();

    emit dataSourceFieldOrExpressionChanged(
        m_widgetDataSourceCombo->fieldOrExpression(),
        m_widgetDataSourceCombo->fieldOrExpressionCaption(),
        dataType
    );
}
Beispiel #3
0
/* As with sqlite, the DB library returns all values (including numbers) as
   strings. So just put that string in a QVariant and let KDb deal with it.
 */
bool MysqlCursor::drv_storeCurrentRecord(KDbRecordData* data) const
{
// mysqlDebug() << "position is " << (long)m_at;
    if (d->numRows == 0)
        return false;

    if (!m_visibleFieldsExpanded) {//simple version: without types
        for (int i = 0; i < m_fieldCount; ++i) {
            (*data)[i] = QString::fromUtf8(d->mysqlrow[i], d->lengths[i]);
        }
        return true;
    }
    for (int i = 0; i < m_fieldCount; ++i) {
        KDbField *f = m_visibleFieldsExpanded->at(i)->field();
        bool ok;
        (*data)[i] = KDb::cstringToVariant(d->mysqlrow[i], f ? f->type() : KDbField::Text,
                                           &ok, d->lengths[i]);
        if (!ok) {
            return false;
        }
    }
    return true;
}
Beispiel #4
0
void KDbRelationship::createIndices(KDbQuerySchema *query, KDbField *field1, KDbField *field2)
{
    if (!field1 || !field2 || !query) {
        kdbWarning() << "!masterField || !detailsField || !query";
        return;
    }
    if (field1->isQueryAsterisk() || field2->isQueryAsterisk()) {
        kdbWarning() << "relationship's fields cannot be asterisks";
        return;
    }
    if (field1->table() == field2->table()) {
        kdbWarning() << "fields cannot belong to the same table";
        return;
    }
    if (!query->contains(field1->table()) || !query->contains(field2->table())) {
        kdbWarning() << "fields do not belong to this query";
        return;
    }
//! @todo: check more things: -types
//! @todo: find existing global db relationships

    KDbField *masterField = 0, *detailsField = 0;
    bool p1 = field1->isPrimaryKey(), p2 = field2->isPrimaryKey();
    if (p1 && p2) {
        //2 primary keys
        masterField = field1;
        m_masterIndex = masterField->table()->primaryKey();
        detailsField = field2;
        m_detailsIndex = detailsField->table()->primaryKey();
    } else if (!p1 && p2) {
        //foreign + primary: swap
        KDbField *tmp = field1;
        field1 = field2;
        field2 = tmp;
        p1 = !p1;
        p2 = !p2;
    }

    if (p1 && !p2) {
        //primary + foreign
        masterField = field1;
        m_masterIndex = masterField->table()->primaryKey();
        detailsField = field2;
        //create foreign key
//@todo: check if it already exists
        m_detailsIndex = new KDbIndexSchema;
        detailsField->table()->addIndex(m_detailsIndex);
        m_detailsIndexOwned = true;
        const bool ok = m_detailsIndex->addField(detailsField);
        Q_ASSERT(ok);
        m_detailsIndex->setForeignKey(true);
    } else if (!p1 && !p2) {
        masterField = field1;
        m_masterIndex = new KDbIndexSchema;
        masterField->table()->addIndex(m_masterIndex);
        m_masterIndexOwned = true;
        bool ok = m_masterIndex->addField(masterField);
        Q_ASSERT(ok);
        m_masterIndex->setForeignKey(true);

        detailsField = field2;
        m_detailsIndex = new KDbIndexSchema;
        detailsField->table()->addIndex(m_detailsIndex);
        m_detailsIndexOwned = true;
        ok = m_detailsIndex->addField(detailsField);
        Q_ASSERT(ok);
        m_detailsIndex->setForeignKey(true);
    }

    if (!m_masterIndex || !m_detailsIndex)
        return; //failed

    (void)setIndices(m_masterIndex, m_detailsIndex, false);
}
Beispiel #5
0
bool KDbRelationship::setIndices(KDbIndexSchema* masterIndex, KDbIndexSchema* detailsIndex, bool ownedByMaster)
{
    m_masterIndex = 0;
    m_detailsIndex = 0;
    m_pairs.clear();
    if (!masterIndex || !detailsIndex || !masterIndex->table() || !detailsIndex->table()
            || masterIndex->table() == detailsIndex->table() || masterIndex->fieldCount() != detailsIndex->fieldCount())
    {
        return false;
    }
    const KDbField::List* masterIndexFields = masterIndex->fields();
    const KDbField::List* detailsIndexFields = detailsIndex->fields();
    KDbField::ListIterator masterIt(masterIndexFields->constBegin());
    KDbField::ListIterator detailsIt(detailsIndexFields->constBegin());
    for (;masterIt != masterIndexFields->constEnd() && detailsIt != detailsIndexFields->constEnd();
            ++masterIt, ++detailsIt) {
        KDbField *masterField = *masterIt;
        KDbField *detailsField = *detailsIt;
        const KDbField::Type masterType = masterField->type(); // cache: evaluating type of expressions can be expensive
        const KDbField::Type detailsType = detailsField->type();
        if (masterType != detailsType
                && KDbField::isIntegerType(masterType) != KDbField::isIntegerType(detailsType)
                && KDbField::isTextType(masterType) != KDbField::isTextType(detailsType))
        {
            kdbWarning() << "INDEX on" << masterIndex->table()->name()
                << ", INDEX on" << detailsIndex->table()->name() << ": !equal field types:"
                << KDbDriver::defaultSQLTypeName(masterType) << masterField->name() << ","
                << KDbDriver::defaultSQLTypeName(detailsType) << detailsField->name();
            m_pairs.clear();
            return false;
        }
#if 0 //too STRICT!
        if ((masterField->isUnsigned() && !detailsField->isUnsigned())
                || (!masterField->isUnsigned() && detailsField->isUnsigned())) {
            kdbWarning() << "KDbRelationship::setIndices(INDEX on '" << masterIndex->table()->name()
            << "',INDEX on " << detailsIndex->table()->name() << "): !equal signedness of field types: "
            << KDbDriver::defaultSQLTypeName(masterField->type()) << " " << masterField->name() << ", "
            << KDbDriver::defaultSQLTypeName(detailsField->type()) << " " << detailsField->name();
            m_pairs.clear();
            return;
        }
#endif
        m_pairs.append(KDbField::Pair(masterField, detailsField));
    }
    //ok: update information
    if (m_masterIndex) {//detach yourself
        m_masterIndex->detachRelationship(this);
    }
    if (m_detailsIndex) {//detach yourself
        m_detailsIndex->detachRelationship(this);
    }
    m_masterIndex = masterIndex;
    m_detailsIndex = detailsIndex;
    m_masterIndex->attachRelationship(this, ownedByMaster);
    m_detailsIndex->attachRelationship(this, ownedByMaster);
    return true;
}
Beispiel #6
0
//==================================================================================
//Return the value for a given column for the current record - Private const version
QVariant PostgresqlCursor::pValue(int pos) const
{
//  postgresqlWarning() << "PostgresqlCursor::value - ERROR: requested position is greater than the number of fields";
    const qint64 row = at();

    KDbField *f = (m_visibleFieldsExpanded && pos < qMin(m_visibleFieldsExpanded->count(), m_fieldCount))
                       ? m_visibleFieldsExpanded->at(pos)->field() : nullptr;
// postgresqlDebug() << "pos:" << pos;

    const KDbField::Type type = m_realTypes[pos];
    const KDbField::Type kdbType = f ? f->type() : KDbField::InvalidType; // cache: evaluating type of expressions can be expensive
    if (PQgetisnull(d->res, row, pos) || kdbType == KDbField::Null) {
        return QVariant();
    }
    const char *data = PQgetvalue(d->res, row, pos);
    int len = PQgetlength(d->res, row, pos);

    switch (type) { // from most to least frequently used types:
    case KDbField::Text:
    case KDbField::LongText: {
        const int maxLength = m_realLengths[pos];
        if (maxLength > 0) {
            len = qMin(len, maxLength);
        }
        return convertToKDbType(!KDbField::isTextType(kdbType),
                                d->unicode ? QString::fromUtf8(data, len) : QString::fromLatin1(data, len),
                                kdbType);
    }
    case KDbField::Integer:
        return convertToKDbType(!KDbField::isIntegerType(kdbType),
                                atoi(data), // the fastest way
                                kdbType);
    case KDbField::Boolean:
        return convertToKDbType(kdbType != KDbField::Boolean,
                                bool(data[0] == 't'),
                                kdbType);
    case KDbField::BigInteger:
        return convertToKDbType(kdbType != KDbField::BigInteger,
                                (data[0] == '-') ? QByteArray::fromRawData(data, len).toLongLong()
                                                 : QByteArray::fromRawData(data, len).toULongLong(),
                                kdbType);
    case KDbField::Double:
//! @todo support equivalent of QSql::NumericalPrecisionPolicy, especially for NUMERICOID
        return convertToKDbType(!KDbField::isFPNumericType(kdbType),
                                QByteArray::fromRawData(data, len).toDouble(),
                                kdbType);
    case KDbField::Date:
        return convertToKDbType(kdbType != KDbField::Date,
                                (len == 0) ? QVariant(QDate())
                                           : QVariant(QDate::fromString(QLatin1String(QByteArray::fromRawData(data, len)), Qt::ISODate)),
                                kdbType);
    case KDbField::Time:
        return convertToKDbType(kdbType != KDbField::Time,
                                timeFromData(data, len),
                                kdbType);
    case KDbField::DateTime:
        return convertToKDbType(kdbType != KDbField::DateTime,
                                dateTimeFromData(data, len),
                                kdbType);
    case KDbField::BLOB:
        return convertToKDbType(kdbType != KDbField::BLOB,
                                byteArrayFromData(data),
                                kdbType);
    default:
        postgresqlWarning() << "PostgresqlCursor::pValue() data type?";
    }
    return QVariant();
}