Changeset View
Changeset View
Standalone View
Standalone View
src/KDbConnection.cpp
Show All 26 Lines | |||||
27 | #include "KDbNativeStatementBuilder.h" | 27 | #include "KDbNativeStatementBuilder.h" | ||
28 | #include "KDbQuerySchema.h" | 28 | #include "KDbQuerySchema.h" | ||
29 | #include "KDbQuerySchema_p.h" | 29 | #include "KDbQuerySchema_p.h" | ||
30 | #include "KDbRecordData.h" | 30 | #include "KDbRecordData.h" | ||
31 | #include "KDbRecordEditBuffer.h" | 31 | #include "KDbRecordEditBuffer.h" | ||
32 | #include "KDbRelationship.h" | 32 | #include "KDbRelationship.h" | ||
33 | #include "KDbSqlRecord.h" | 33 | #include "KDbSqlRecord.h" | ||
34 | #include "KDbSqlResult.h" | 34 | #include "KDbSqlResult.h" | ||
35 | #include "KDbTableOrQuerySchema.h" | ||||
35 | #include "KDbTableSchemaChangeListener.h" | 36 | #include "KDbTableSchemaChangeListener.h" | ||
36 | #include "KDbTransactionData.h" | 37 | #include "KDbTransactionData.h" | ||
37 | #include "KDbTransactionGuard.h" | 38 | #include "KDbTransactionGuard.h" | ||
38 | #include "kdb_debug.h" | 39 | #include "kdb_debug.h" | ||
39 | 40 | | |||
40 | #include <QDir> | 41 | #include <QDir> | ||
41 | #include <QFileInfo> | 42 | #include <QFileInfo> | ||
42 | #include <QDomDocument> | 43 | #include <QDomDocument> | ||
▲ Show 20 Lines • Show All 2891 Lines • ▼ Show 20 Line(s) | |||||
2934 | 2935 | | |||
2935 | KDbQuerySchema* KDbConnection::querySchema(const QString& aQueryName) | 2936 | KDbQuerySchema* KDbConnection::querySchema(const QString& aQueryName) | ||
2936 | { | 2937 | { | ||
2937 | QString queryName = aQueryName.toLower(); | 2938 | QString queryName = aQueryName.toLower(); | ||
2938 | KDbQuerySchema *q = d->query(queryName); | 2939 | KDbQuerySchema *q = d->query(queryName); | ||
2939 | if (q) | 2940 | if (q) | ||
2940 | return q; | 2941 | return q; | ||
2941 | //not found: retrieve schema | 2942 | //not found: retrieve schema | ||
2942 | QScopedPointer<KDbQuerySchema> newQuery(KDbQuerySchema::Private::createQuery(this)); | 2943 | QScopedPointer<KDbQuerySchema> newQuery(new KDbQuerySchema); | ||
2943 | clearResult(); | 2944 | clearResult(); | ||
2944 | if (true != loadObjectData(KDb::QueryObjectType, aQueryName, newQuery.data())) { | 2945 | if (true != loadObjectData(KDb::QueryObjectType, aQueryName, newQuery.data())) { | ||
2945 | return nullptr; | 2946 | return nullptr; | ||
2946 | } | 2947 | } | ||
2947 | return d->setupQuerySchema(newQuery.take()); | 2948 | return d->setupQuerySchema(newQuery.take()); | ||
2948 | } | 2949 | } | ||
2949 | 2950 | | |||
2950 | KDbQuerySchema* KDbConnection::querySchema(int queryId) | 2951 | KDbQuerySchema* KDbConnection::querySchema(int queryId) | ||
2951 | { | 2952 | { | ||
2952 | KDbQuerySchema *q = d->query(queryId); | 2953 | KDbQuerySchema *q = d->query(queryId); | ||
2953 | if (q) | 2954 | if (q) | ||
2954 | return q; | 2955 | return q; | ||
2955 | //not found: retrieve schema | 2956 | //not found: retrieve schema | ||
2956 | QScopedPointer<KDbQuerySchema> newQuery(KDbQuerySchema::Private::createQuery(this)); | 2957 | QScopedPointer<KDbQuerySchema> newQuery(new KDbQuerySchema); | ||
2957 | clearResult(); | 2958 | clearResult(); | ||
2958 | if (true != loadObjectData(KDb::QueryObjectType, queryId, newQuery.data())) { | 2959 | if (true != loadObjectData(KDb::QueryObjectType, queryId, newQuery.data())) { | ||
2959 | return nullptr; | 2960 | return nullptr; | ||
2960 | } | 2961 | } | ||
2961 | return d->setupQuerySchema(newQuery.take()); | 2962 | return d->setupQuerySchema(newQuery.take()); | ||
2962 | } | 2963 | } | ||
2963 | 2964 | | |||
2964 | bool KDbConnection::setQuerySchemaObsolete(const QString& queryName) | 2965 | bool KDbConnection::setQuerySchemaObsolete(const QString& queryName) | ||
Show All 35 Lines | |||||
3000 | } | 3001 | } | ||
3001 | 3002 | | |||
3002 | void KDbConnection::setAvailableDatabaseName(const QString& dbName) | 3003 | void KDbConnection::setAvailableDatabaseName(const QString& dbName) | ||
3003 | { | 3004 | { | ||
3004 | d->availableDatabaseName = dbName; | 3005 | d->availableDatabaseName = dbName; | ||
3005 | } | 3006 | } | ||
3006 | 3007 | | |||
3007 | //! @internal used in updateRecord(), insertRecord(), | 3008 | //! @internal used in updateRecord(), insertRecord(), | ||
3008 | inline static void updateRecordDataWithNewValues(KDbQuerySchema* query, KDbRecordData* data, | 3009 | inline static void updateRecordDataWithNewValues( | ||
3010 | KDbConnection *conn, KDbQuerySchema* query, KDbRecordData* data, | ||||
3009 | const KDbRecordEditBuffer::DbHash& b, | 3011 | const KDbRecordEditBuffer::DbHash& b, | ||
3010 | QHash<KDbQueryColumnInfo*, int>* columnsOrderExpanded) | 3012 | QHash<KDbQueryColumnInfo*, int>* columnsOrderExpanded) | ||
3011 | { | 3013 | { | ||
3012 | *columnsOrderExpanded = query->columnsOrder(KDbQuerySchema::ExpandedList); | 3014 | *columnsOrderExpanded | ||
3015 | = query->columnsOrder(conn, KDbQuerySchema::ColumnsOrderMode::ExpandedList); | ||||
3013 | QHash<KDbQueryColumnInfo*, int>::ConstIterator columnsOrderExpandedIt; | 3016 | QHash<KDbQueryColumnInfo*, int>::ConstIterator columnsOrderExpandedIt; | ||
3014 | for (KDbRecordEditBuffer::DbHash::ConstIterator it = b.constBegin();it != b.constEnd();++it) { | 3017 | for (KDbRecordEditBuffer::DbHash::ConstIterator it = b.constBegin();it != b.constEnd();++it) { | ||
3015 | columnsOrderExpandedIt = columnsOrderExpanded->constFind(it.key()); | 3018 | columnsOrderExpandedIt = columnsOrderExpanded->constFind(it.key()); | ||
3016 | if (columnsOrderExpandedIt == columnsOrderExpanded->constEnd()) { | 3019 | if (columnsOrderExpandedIt == columnsOrderExpanded->constEnd()) { | ||
3017 | kdbWarning() << "(KDbConnection) \"now also assign new value in memory\" step" | 3020 | kdbWarning() << "(KDbConnection) \"now also assign new value in memory\" step" | ||
3018 | "- could not find item" << it.key()->aliasOrName(); | 3021 | "- could not find item" << it.key()->aliasOrName(); | ||
3019 | continue; | 3022 | continue; | ||
3020 | } | 3023 | } | ||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Line(s) | 3068 | if (!sqlset.isEmpty()) | |||
3066 | sqlset += ','; | 3069 | sqlset += ','; | ||
3067 | KDbField* currentField = it.key()->field(); | 3070 | KDbField* currentField = it.key()->field(); | ||
3068 | const bool affectedFieldsAddOk = affectedFields.addField(currentField); | 3071 | const bool affectedFieldsAddOk = affectedFields.addField(currentField); | ||
3069 | Q_ASSERT(affectedFieldsAddOk); | 3072 | Q_ASSERT(affectedFieldsAddOk); | ||
3070 | sqlset += KDbEscapedString(escapeIdentifier(currentField->name())) + '=' + | 3073 | sqlset += KDbEscapedString(escapeIdentifier(currentField->name())) + '=' + | ||
3071 | d->driver->valueToSql(currentField, it.value()); | 3074 | d->driver->valueToSql(currentField, it.value()); | ||
3072 | } | 3075 | } | ||
3073 | if (pkey) { | 3076 | if (pkey) { | ||
3074 | const QVector<int> pkeyFieldsOrder(query->pkeyFieldsOrder()); | 3077 | const QVector<int> pkeyFieldsOrder(query->pkeyFieldsOrder(this)); | ||
3075 | //kdbDebug() << pkey->fieldCount() << " ? " << query->pkeyFieldCount(); | 3078 | //kdbDebug() << pkey->fieldCount() << " ? " << query->pkeyFieldCount(); | ||
3076 | if (pkey->fieldCount() != query->pkeyFieldCount()) { //sanity check | 3079 | if (pkey->fieldCount() != query->pkeyFieldCount(this)) { //sanity check | ||
3077 | kdbWarning() << " -- NO ENTIRE MASTER TABLE's PKEY SPECIFIED!"; | 3080 | kdbWarning() << " -- NO ENTIRE MASTER TABLE's PKEY SPECIFIED!"; | ||
3078 | m_result = KDbResult(ERR_UPDATE_NO_ENTIRE_MASTER_TABLES_PKEY, | 3081 | m_result = KDbResult(ERR_UPDATE_NO_ENTIRE_MASTER_TABLES_PKEY, | ||
3079 | tr("Could not update record because it does not contain entire primary key of master table.")); | 3082 | tr("Could not update record because it does not contain entire primary key of master table.")); | ||
3080 | return false; | 3083 | return false; | ||
3081 | } | 3084 | } | ||
3082 | if (!pkey->fields()->isEmpty()) { | 3085 | if (!pkey->fields()->isEmpty()) { | ||
3083 | int i = 0; | 3086 | int i = 0; | ||
3084 | foreach(KDbField *f, *pkey->fields()) { | 3087 | foreach(KDbField *f, *pkey->fields()) { | ||
Show All 30 Lines | |||||
3115 | 3118 | | |||
3116 | if (!res) { | 3119 | if (!res) { | ||
3117 | m_result = KDbResult(ERR_UPDATE_SERVER_ERROR, | 3120 | m_result = KDbResult(ERR_UPDATE_SERVER_ERROR, | ||
3118 | tr("Record updating on the server failed.")); | 3121 | tr("Record updating on the server failed.")); | ||
3119 | return false; | 3122 | return false; | ||
3120 | } | 3123 | } | ||
3121 | //success: now also assign new values in memory: | 3124 | //success: now also assign new values in memory: | ||
3122 | QHash<KDbQueryColumnInfo*, int> columnsOrderExpanded; | 3125 | QHash<KDbQueryColumnInfo*, int> columnsOrderExpanded; | ||
3123 | updateRecordDataWithNewValues(query, data, b, &columnsOrderExpanded); | 3126 | updateRecordDataWithNewValues(this, query, data, b, &columnsOrderExpanded); | ||
3124 | return true; | 3127 | return true; | ||
3125 | } | 3128 | } | ||
3126 | 3129 | | |||
3127 | bool KDbConnection::insertRecord(KDbQuerySchema* query, KDbRecordData* data, KDbRecordEditBuffer* buf, bool getRecordId) | 3130 | bool KDbConnection::insertRecord(KDbQuerySchema* query, KDbRecordData* data, KDbRecordEditBuffer* buf, bool getRecordId) | ||
3128 | { | 3131 | { | ||
3129 | // Each SQL identifier needs to be escaped in the generated query. | 3132 | // Each SQL identifier needs to be escaped in the generated query. | ||
3130 | clearResult(); | 3133 | clearResult(); | ||
3131 | //--get PKEY | 3134 | //--get PKEY | ||
Show All 20 Lines | |||||
3152 | 3155 | | |||
3153 | //insert the record: | 3156 | //insert the record: | ||
3154 | KDbEscapedString sql; | 3157 | KDbEscapedString sql; | ||
3155 | sql.reserve(4096); | 3158 | sql.reserve(4096); | ||
3156 | sql = KDbEscapedString("INSERT INTO ") + escapeIdentifier(mt->name()) + " ("; | 3159 | sql = KDbEscapedString("INSERT INTO ") + escapeIdentifier(mt->name()) + " ("; | ||
3157 | KDbRecordEditBuffer::DbHash b = buf->dbBuffer(); | 3160 | KDbRecordEditBuffer::DbHash b = buf->dbBuffer(); | ||
3158 | 3161 | | |||
3159 | // add default values, if available (for any column without value explicitly set) | 3162 | // add default values, if available (for any column without value explicitly set) | ||
3160 | const KDbQueryColumnInfo::Vector fieldsExpanded(query->fieldsExpanded(KDbQuerySchema::Unique)); | 3163 | const KDbQueryColumnInfo::Vector fieldsExpanded( | ||
3164 | query->fieldsExpanded(this, KDbQuerySchema::FieldsExpandedMode::Unique)); | ||||
3161 | int fieldsExpandedCount = fieldsExpanded.count(); | 3165 | int fieldsExpandedCount = fieldsExpanded.count(); | ||
3162 | for (int i = 0; i < fieldsExpandedCount; i++) { | 3166 | for (int i = 0; i < fieldsExpandedCount; i++) { | ||
3163 | KDbQueryColumnInfo *ci = fieldsExpanded.at(i); | 3167 | KDbQueryColumnInfo *ci = fieldsExpanded.at(i); | ||
3164 | if (ci->field() && KDb::isDefaultValueAllowed(*ci->field()) | 3168 | if (ci->field() && KDb::isDefaultValueAllowed(*ci->field()) | ||
3165 | && !ci->field()->defaultValue().isNull() | 3169 | && !ci->field()->defaultValue().isNull() | ||
3166 | && !b.contains(ci)) | 3170 | && !b.contains(ci)) | ||
3167 | { | 3171 | { | ||
3168 | //kdbDebug() << "adding default value" << ci->field->defaultValue().toString() << "for column" << ci->field->name(); | 3172 | //kdbDebug() << "adding default value" << ci->field->defaultValue().toString() << "for column" << ci->field->name(); | ||
3169 | b.insert(ci, ci->field()->defaultValue()); | 3173 | b.insert(ci, ci->field()->defaultValue()); | ||
3170 | } | 3174 | } | ||
3171 | } | 3175 | } | ||
3172 | 3176 | | |||
3173 | //collect fields which have values in KDbRecordEditBuffer | 3177 | //collect fields which have values in KDbRecordEditBuffer | ||
3174 | KDbFieldList affectedFields; | 3178 | KDbFieldList affectedFields; | ||
3175 | 3179 | | |||
3176 | if (b.isEmpty()) { | 3180 | if (b.isEmpty()) { | ||
3177 | // empty record inserting requested: | 3181 | // empty record inserting requested: | ||
3178 | if (!getRecordId && !pkey) { | 3182 | if (!getRecordId && !pkey) { | ||
3179 | kdbWarning() << "MASTER TABLE's PKEY REQUIRED FOR INSERTING EMPTY RECORDS: INSERT CANCELLED"; | 3183 | kdbWarning() << "MASTER TABLE's PKEY REQUIRED FOR INSERTING EMPTY RECORDS: INSERT CANCELLED"; | ||
3180 | m_result = KDbResult(ERR_INSERT_NO_MASTER_TABLES_PKEY, | 3184 | m_result = KDbResult(ERR_INSERT_NO_MASTER_TABLES_PKEY, | ||
3181 | tr("Could not insert record because master table has no primary key specified.")); | 3185 | tr("Could not insert record because master table has no primary key specified.")); | ||
3182 | return false; | 3186 | return false; | ||
3183 | } | 3187 | } | ||
3184 | if (pkey) { | 3188 | if (pkey) { | ||
3185 | const QVector<int> pkeyFieldsOrder(query->pkeyFieldsOrder()); | 3189 | const QVector<int> pkeyFieldsOrder(query->pkeyFieldsOrder(this)); | ||
3186 | // kdbDebug() << pkey->fieldCount() << " ? " << query->pkeyFieldCount(); | 3190 | // kdbDebug() << pkey->fieldCount() << " ? " << query->pkeyFieldCount(); | ||
3187 | if (pkey->fieldCount() != query->pkeyFieldCount()) { // sanity check | 3191 | if (pkey->fieldCount() != query->pkeyFieldCount(this)) { // sanity check | ||
3188 | kdbWarning() << "NO ENTIRE MASTER TABLE's PKEY SPECIFIED!"; | 3192 | kdbWarning() << "NO ENTIRE MASTER TABLE's PKEY SPECIFIED!"; | ||
3189 | m_result = KDbResult(ERR_INSERT_NO_ENTIRE_MASTER_TABLES_PKEY, | 3193 | m_result = KDbResult(ERR_INSERT_NO_ENTIRE_MASTER_TABLES_PKEY, | ||
3190 | tr("Could not insert record because it does not contain " | 3194 | tr("Could not insert record because it does not contain " | ||
3191 | "entire master table's primary key.")); | 3195 | "entire master table's primary key.")); | ||
3192 | return false; | 3196 | return false; | ||
3193 | } | 3197 | } | ||
3194 | } | 3198 | } | ||
3195 | //at least one value is needed for VALUES section: find it and set to NULL: | 3199 | //at least one value is needed for VALUES section: find it and set to NULL: | ||
Show All 34 Lines | 3231 | // kdbDebug() << " -- SQL == " << sql; | |||
3230 | QSharedPointer<KDbSqlResult> result = insertRecordInternal(mt->name(), &affectedFields, sql); | 3234 | QSharedPointer<KDbSqlResult> result = insertRecordInternal(mt->name(), &affectedFields, sql); | ||
3231 | if (!result) { | 3235 | if (!result) { | ||
3232 | m_result = KDbResult(ERR_INSERT_SERVER_ERROR, | 3236 | m_result = KDbResult(ERR_INSERT_SERVER_ERROR, | ||
3233 | tr("Record inserting on the server failed.")); | 3237 | tr("Record inserting on the server failed.")); | ||
3234 | return false; | 3238 | return false; | ||
3235 | } | 3239 | } | ||
3236 | //success: now also assign a new value in memory: | 3240 | //success: now also assign a new value in memory: | ||
3237 | QHash<KDbQueryColumnInfo*, int> columnsOrderExpanded; | 3241 | QHash<KDbQueryColumnInfo*, int> columnsOrderExpanded; | ||
3238 | updateRecordDataWithNewValues(query, data, b, &columnsOrderExpanded); | 3242 | updateRecordDataWithNewValues(this, query, data, b, &columnsOrderExpanded); | ||
3239 | 3243 | | |||
3240 | //fetch autoincremented values | 3244 | //fetch autoincremented values | ||
3241 | KDbQueryColumnInfo::List *aif_list = query->autoIncrementFields(); | 3245 | KDbQueryColumnInfo::List *aif_list = query->autoIncrementFields(this); | ||
3242 | quint64 recordId = 0; | 3246 | quint64 recordId = 0; | ||
3243 | if (pkey && !aif_list->isEmpty()) { | 3247 | if (pkey && !aif_list->isEmpty()) { | ||
3244 | //! @todo now only if PKEY is present, this should also work when there's no PKEY | 3248 | //! @todo now only if PKEY is present, this should also work when there's no PKEY | ||
3245 | KDbQueryColumnInfo *id_columnInfo = aif_list->first(); | 3249 | KDbQueryColumnInfo *id_columnInfo = aif_list->first(); | ||
3246 | //! @todo safe to cast it? | 3250 | //! @todo safe to cast it? | ||
3247 | quint64 last_id | 3251 | quint64 last_id | ||
3248 | = KDb::lastInsertedAutoIncValue(result, id_columnInfo->field()->name(), | 3252 | = KDb::lastInsertedAutoIncValue(result, id_columnInfo->field()->name(), | ||
3249 | id_columnInfo->field()->table()->name(), &recordId); | 3253 | id_columnInfo->field()->table()->name(), &recordId); | ||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Line(s) | 3306 | //! @todo allow to delete from a table without pkey | |||
3310 | //update the record: | 3314 | //update the record: | ||
3311 | KDbEscapedString sql; | 3315 | KDbEscapedString sql; | ||
3312 | sql.reserve(4096); | 3316 | sql.reserve(4096); | ||
3313 | sql = KDbEscapedString("DELETE FROM ") + escapeIdentifier(mt->name()) + " WHERE "; | 3317 | sql = KDbEscapedString("DELETE FROM ") + escapeIdentifier(mt->name()) + " WHERE "; | ||
3314 | KDbEscapedString sqlwhere; | 3318 | KDbEscapedString sqlwhere; | ||
3315 | sqlwhere.reserve(1024); | 3319 | sqlwhere.reserve(1024); | ||
3316 | 3320 | | |||
3317 | if (pkey) { | 3321 | if (pkey) { | ||
3318 | const QVector<int> pkeyFieldsOrder(query->pkeyFieldsOrder()); | 3322 | const QVector<int> pkeyFieldsOrder(query->pkeyFieldsOrder(this)); | ||
3319 | //kdbDebug() << pkey->fieldCount() << " ? " << query->pkeyFieldCount(); | 3323 | //kdbDebug() << pkey->fieldCount() << " ? " << query->pkeyFieldCount(); | ||
3320 | if (pkey->fieldCount() != query->pkeyFieldCount()) { //sanity check | 3324 | if (pkey->fieldCount() != query->pkeyFieldCount(this)) { //sanity check | ||
3321 | kdbWarning() << " -- NO ENTIRE MASTER TABLE's PKEY SPECIFIED!"; | 3325 | kdbWarning() << " -- NO ENTIRE MASTER TABLE's PKEY SPECIFIED!"; | ||
3322 | m_result = KDbResult(ERR_DELETE_NO_ENTIRE_MASTER_TABLES_PKEY, | 3326 | m_result = KDbResult(ERR_DELETE_NO_ENTIRE_MASTER_TABLES_PKEY, | ||
3323 | tr("Could not delete record because it does not contain entire master table's primary key.")); | 3327 | tr("Could not delete record because it does not contain entire master table's primary key.")); | ||
3324 | return false; | 3328 | return false; | ||
3325 | } | 3329 | } | ||
3326 | int i = 0; | 3330 | int i = 0; | ||
3327 | foreach(KDbField *f, *pkey->fields()) { | 3331 | foreach(KDbField *f, *pkey->fields()) { | ||
3328 | if (!sqlwhere.isEmpty()) | 3332 | if (!sqlwhere.isEmpty()) | ||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Line(s) | 3361 | { | |||
3371 | if (!executeSql(sql)) { | 3375 | if (!executeSql(sql)) { | ||
3372 | m_result = KDbResult(ERR_DELETE_SERVER_ERROR, | 3376 | m_result = KDbResult(ERR_DELETE_SERVER_ERROR, | ||
3373 | tr("Record deletion on the server failed.")); | 3377 | tr("Record deletion on the server failed.")); | ||
3374 | return false; | 3378 | return false; | ||
3375 | } | 3379 | } | ||
3376 | return true; | 3380 | return true; | ||
3377 | } | 3381 | } | ||
3378 | 3382 | | |||
3383 | int KDbConnection::recordCount(const KDbEscapedString& sql) | ||||
3384 | { | ||||
3385 | int count = -1; //will be changed only on success of querySingleNumber() | ||||
3386 | const tristate result = querySingleNumber( | ||||
3387 | KDbEscapedString("SELECT COUNT() FROM (") + sql + ") AS kdb__subquery", &count); | ||||
3388 | if (~result) { | ||||
3389 | count = 0; | ||||
3390 | } | ||||
3391 | return count; | ||||
3392 | } | ||||
3393 | | ||||
3394 | int KDbConnection::recordCount(const KDbTableSchema& tableSchema) | ||||
3395 | { | ||||
3396 | //! @todo does not work with non-SQL data sources | ||||
3397 | int count = -1; // will be changed only on success of querySingleNumber() | ||||
3398 | const tristate result | ||||
3399 | = querySingleNumber(KDbEscapedString("SELECT COUNT(*) FROM ") | ||||
3400 | + tableSchema.connection()->escapeIdentifier(tableSchema.name()), | ||||
3401 | &count); | ||||
3402 | if (~result) { | ||||
3403 | count = 0; | ||||
3404 | } | ||||
3405 | return count; | ||||
3406 | } | ||||
3407 | | ||||
3408 | int KDbConnection::recordCount(KDbQuerySchema* querySchema, const QList<QVariant>& params) | ||||
3409 | { | ||||
3410 | //! @todo does not work with non-SQL data sources | ||||
3411 | int count = -1; //will be changed only on success of querySingleNumber() | ||||
3412 | KDbNativeStatementBuilder builder(this); | ||||
3413 | KDbEscapedString subSql; | ||||
3414 | if (!builder.generateSelectStatement(&subSql, querySchema, params)) { | ||||
3415 | return -1; | ||||
3416 | } | ||||
3417 | const tristate result = querySingleNumber( | ||||
3418 | KDbEscapedString("SELECT COUNT(*) FROM (") + subSql + ") AS kdb__subquery", &count); | ||||
3419 | if (~result) { | ||||
3420 | count = 0; | ||||
3421 | } | ||||
3422 | return count; | ||||
3423 | } | ||||
3424 | | ||||
3425 | int KDbConnection::recordCount(KDbTableOrQuerySchema* tableOrQuery, const QList<QVariant>& params) | ||||
3426 | { | ||||
3427 | if (tableOrQuery) { | ||||
3428 | if (tableOrQuery->table()) | ||||
3429 | return recordCount(*tableOrQuery->table()); | ||||
3430 | if (tableOrQuery->query()) | ||||
3431 | return recordCount(tableOrQuery->query(), params); | ||||
3432 | } | ||||
3433 | return -1; | ||||
3434 | } | ||||
3435 | | ||||
3379 | KDbConnectionOptions* KDbConnection::options() | 3436 | KDbConnectionOptions* KDbConnection::options() | ||
3380 | { | 3437 | { | ||
3381 | return &d->options; | 3438 | return &d->options; | ||
3382 | } | 3439 | } | ||
3383 | 3440 | | |||
3384 | void KDbConnection::addCursor(KDbCursor* cursor) | 3441 | void KDbConnection::addCursor(KDbCursor* cursor) | ||
3385 | { | 3442 | { | ||
3386 | d->cursors.insert(cursor); | 3443 | d->cursors.insert(cursor); | ||
Show All 34 Lines |