Changeset View
Changeset View
Standalone View
Standalone View
src/KDbConnection.cpp
Show First 20 Lines • Show All 986 Lines • ▼ Show 20 Line(s) | |||||
987 | #define V_A0 d->driver->valueToSQL( tableSchema->field(0), c0 ) | 987 | #define V_A0 d->driver->valueToSQL( tableSchema->field(0), c0 ) | ||
988 | #define V_A(a) + ',' + d->driver->valueToSQL( \ | 988 | #define V_A(a) + ',' + d->driver->valueToSQL( \ | ||
989 | tableSchema->field(a) ? tableSchema->field(a)->type() : KDbField::Text, c ## a ) | 989 | tableSchema->field(a) ? tableSchema->field(a)->type() : KDbField::Text, c ## a ) | ||
990 | 990 | | |||
991 | // kdbDebug() << "******** " << QString("INSERT INTO ") + | 991 | // kdbDebug() << "******** " << QString("INSERT INTO ") + | ||
992 | // escapeIdentifier(tableSchema->name()) + | 992 | // escapeIdentifier(tableSchema->name()) + | ||
993 | // " VALUES (" + vals + ")"; | 993 | // " VALUES (" + vals + ")"; | ||
994 | 994 | | |||
995 | bool KDbConnection::insertRecordInternal(const QString &tableSchemaName, KDbFieldList* fields, | 995 | QSharedPointer<KDbSqlResult> KDbConnection::insertRecordInternal(const QString &tableSchemaName, | ||
996 | const KDbEscapedString &sql, KDbSqlResult** result = nullptr) | 996 | KDbFieldList *fields, | ||
997 | const KDbEscapedString &sql) | ||||
997 | { | 998 | { | ||
999 | QSharedPointer<KDbSqlResult> res; | ||||
998 | if (!drv_beforeInsert(tableSchemaName,fields )) { | 1000 | if (!drv_beforeInsert(tableSchemaName,fields )) { | ||
999 | return false; | 1001 | return res; | ||
1000 | } | 1002 | } | ||
1001 | QScopedPointer<KDbSqlResult> res(executeSQL(sql)); | 1003 | res = prepareSql(sql); | ||
1002 | if (!res || res->lastResult().isError()) { | 1004 | if (!res || res->lastResult().isError()) { | ||
1003 | return false; | 1005 | res.clear(); | ||
1006 | return res; | ||||
1004 | } | 1007 | } | ||
1005 | if (!drv_afterInsert(tableSchemaName, fields)) { | 1008 | if (!drv_afterInsert(tableSchemaName, fields)) { | ||
1006 | return false; | 1009 | res.clear(); | ||
1010 | return res; | ||||
1007 | } | 1011 | } | ||
1008 | { | 1012 | { | ||
1009 | // Fetching is needed to performs real execution, at least for some backends. | 1013 | // Fetching is needed to perform real execution at least for some backends. | ||
1010 | // Also we're not expecting record but let's delete if there's any. | 1014 | // Also we are not expecting record but let's delete if there's any. | ||
1011 | QScopedPointer<KDbSqlRecord> record(res->fetchRecord()); | 1015 | (void)res->fetchRecord(); | ||
1012 | } | | |||
1013 | if (!res->lastResult().isError()) { | | |||
1014 | if (result) { | | |||
1015 | *result = res.take(); | | |||
1016 | } | 1016 | } | ||
1017 | return true; | 1017 | if (res->lastResult().isError()) { | ||
1018 | res.clear(); | ||||
1018 | } | 1019 | } | ||
1019 | return false; | 1020 | return res; | ||
1020 | } | 1021 | } | ||
1021 | 1022 | | |||
1022 | #define C_INS_REC(args, vals) \ | 1023 | #define C_INS_REC(args, vals) \ | ||
1023 | bool KDbConnection::insertRecord(KDbTableSchema* tableSchema args, KDbSqlResult** result) {\ | 1024 | QSharedPointer<KDbSqlResult> KDbConnection::insertRecord(KDbTableSchema* tableSchema args) { \ | ||
1024 | return insertRecordInternal(tableSchema->name(), tableSchema, \ | 1025 | return insertRecordInternal(tableSchema->name(), tableSchema, \ | ||
1025 | KDbEscapedString("INSERT INTO ") + escapeIdentifier(tableSchema->name()) \ | 1026 | KDbEscapedString("INSERT INTO ") + escapeIdentifier(tableSchema->name()) \ | ||
1026 | + " (" \ | 1027 | + " (" \ | ||
1027 | + tableSchema->sqlFieldsList(this) \ | 1028 | + tableSchema->sqlFieldsList(this) \ | ||
1028 | + ") VALUES (" + vals + ")", \ | 1029 | + ") VALUES (" + vals + ')'); \ | ||
1029 | result); \ | | |||
1030 | } | 1030 | } | ||
1031 | 1031 | | |||
1032 | #define C_INS_REC_ALL \ | 1032 | #define C_INS_REC_ALL \ | ||
1033 | C_INS_REC( C_A(0), V_A0 ) \ | 1033 | C_INS_REC( C_A(0), V_A0 ) \ | ||
1034 | C_INS_REC( C_A(0) C_A(1), V_A0 V_A(1) ) \ | 1034 | C_INS_REC( C_A(0) C_A(1), V_A0 V_A(1) ) \ | ||
1035 | C_INS_REC( C_A(0) C_A(1) C_A(2), V_A0 V_A(1) V_A(2) ) \ | 1035 | C_INS_REC( C_A(0) C_A(1) C_A(2), V_A0 V_A(1) V_A(2) ) \ | ||
1036 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3), V_A0 V_A(1) V_A(2) V_A(3) ) \ | 1036 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3), V_A0 V_A(1) V_A(2) V_A(3) ) \ | ||
1037 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3) C_A(4), V_A0 V_A(1) V_A(2) V_A(3) V_A(4) ) \ | 1037 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3) C_A(4), V_A0 V_A(1) V_A(2) V_A(3) V_A(4) ) \ | ||
1038 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3) C_A(4) C_A(5), V_A0 V_A(1) V_A(2) V_A(3) V_A(4) V_A(5) ) \ | 1038 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3) C_A(4) C_A(5), V_A0 V_A(1) V_A(2) V_A(3) V_A(4) V_A(5) ) \ | ||
1039 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3) C_A(4) C_A(5) C_A(6), V_A0 V_A(1) V_A(2) V_A(3) V_A(4) V_A(5) V_A(6) ) \ | 1039 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3) C_A(4) C_A(5) C_A(6), V_A0 V_A(1) V_A(2) V_A(3) V_A(4) V_A(5) V_A(6) ) \ | ||
1040 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3) C_A(4) C_A(5) C_A(6) C_A(7), V_A0 V_A(1) V_A(2) V_A(3) V_A(4) V_A(5) V_A(6) V_A(7) ) | 1040 | C_INS_REC( C_A(0) C_A(1) C_A(2) C_A(3) C_A(4) C_A(5) C_A(6) C_A(7), V_A0 V_A(1) V_A(2) V_A(3) V_A(4) V_A(5) V_A(6) V_A(7) ) | ||
1041 | 1041 | | |||
1042 | C_INS_REC_ALL | 1042 | C_INS_REC_ALL | ||
1043 | 1043 | | |||
1044 | #undef V_A0 | 1044 | #undef V_A0 | ||
1045 | #undef V_A | 1045 | #undef V_A | ||
1046 | #undef C_INS_REC | 1046 | #undef C_INS_REC | ||
1047 | 1047 | | |||
1048 | #define V_A0 value += d->driver->valueToSQL( it.next(), c0 ); | 1048 | #define V_A0 value += d->driver->valueToSQL( it.next(), c0 ); | ||
1049 | #define V_A( a ) value += (',' + d->driver->valueToSQL( it.next(), c ## a )); | 1049 | #define V_A( a ) value += (',' + d->driver->valueToSQL( it.next(), c ## a )); | ||
1050 | 1050 | | |||
1051 | #define C_INS_REC(args, vals) \ | 1051 | #define C_INS_REC(args, vals) \ | ||
1052 | bool KDbConnection::insertRecord(KDbFieldList* fields args, KDbSqlResult** result) \ | 1052 | QSharedPointer<KDbSqlResult> KDbConnection::insertRecord(KDbFieldList* fields args) \ | ||
1053 | { \ | 1053 | { \ | ||
1054 | KDbEscapedString value; \ | 1054 | KDbEscapedString value; \ | ||
1055 | const KDbField::List *flist = fields->fields(); \ | 1055 | const KDbField::List *flist = fields->fields(); \ | ||
1056 | QListIterator<KDbField*> it(*flist); \ | 1056 | QListIterator<KDbField*> it(*flist); \ | ||
1057 | vals \ | 1057 | vals \ | ||
1058 | it.toFront(); \ | 1058 | it.toFront(); \ | ||
1059 | QString tableName((it.hasNext() && it.peekNext()->table()) ? it.next()->table()->name() : QLatin1String("??")); \ | 1059 | QString tableName((it.hasNext() && it.peekNext()->table()) ? it.next()->table()->name() : QLatin1String("??")); \ | ||
1060 | return insertRecordInternal(tableName, fields, \ | 1060 | return insertRecordInternal(tableName, fields, \ | ||
1061 | KDbEscapedString(QLatin1String("INSERT INTO ") + escapeIdentifier(tableName)) \ | 1061 | KDbEscapedString(QLatin1String("INSERT INTO ") + escapeIdentifier(tableName)) \ | ||
1062 | + " (" + fields->sqlFieldsList(this) \ | 1062 | + " (" + fields->sqlFieldsList(this) \ | ||
1063 | + ") VALUES (" + value + ')', \ | 1063 | + ") VALUES (" + value + ')'); \ | ||
1064 | result); \ | | |||
1065 | } | 1064 | } | ||
1066 | 1065 | | |||
1067 | C_INS_REC_ALL | 1066 | C_INS_REC_ALL | ||
1068 | 1067 | | |||
1069 | #undef C_A | 1068 | #undef C_A | ||
1070 | #undef V_A | 1069 | #undef V_A | ||
1071 | #undef V_ALAST | 1070 | #undef V_ALAST | ||
1072 | #undef C_INS_REC | 1071 | #undef C_INS_REC | ||
1073 | #undef C_INS_REC_ALL | 1072 | #undef C_INS_REC_ALL | ||
1074 | 1073 | | |||
1075 | bool KDbConnection::insertRecord(KDbTableSchema* tableSchema, const QList<QVariant>& values, | 1074 | QSharedPointer<KDbSqlResult> KDbConnection::insertRecord(KDbTableSchema *tableSchema, | ||
1076 | KDbSqlResult** result) | 1075 | const QList<QVariant> &values) | ||
anthonyfieroni: Pointer is passed when argument can be optional i.e. nullptr, by reference when it can't be… | |||||
What you say works but we're using the Qt API design guidelines. Like Q*Event* is used everywhere in QWidget::*Event(QEvent *) even while it's required. In other words, do you know a place in, say, QtSql and further in Qt or even KF5 that uses nonconst-references for the mentioned reason? Another topic is missing assertions or checks for such code. staniek: What you say works but we're using the Qt API design guidelines. Like `Q*Event*` is used… | |||||
1077 | { | 1076 | { | ||
1078 | // Each SQL identifier needs to be escaped in the generated query. | 1077 | // Each SQL identifier needs to be escaped in the generated query. | ||
1078 | QSharedPointer<KDbSqlResult> res; | ||||
1079 | const KDbField::List *flist = tableSchema->fields(); | 1079 | const KDbField::List *flist = tableSchema->fields(); | ||
1080 | if (flist->isEmpty()) { | 1080 | if (flist->isEmpty()) { | ||
1081 | return false; | 1081 | return res; | ||
1082 | } | 1082 | } | ||
1083 | KDbField::ListIterator fieldsIt(flist->constBegin()); | 1083 | KDbField::ListIterator fieldsIt(flist->constBegin()); | ||
1084 | QList<QVariant>::ConstIterator it = values.constBegin(); | 1084 | QList<QVariant>::ConstIterator it = values.constBegin(); | ||
1085 | KDbEscapedString sql; | 1085 | KDbEscapedString sql; | ||
1086 | sql.reserve(4096); | 1086 | sql.reserve(4096); | ||
1087 | while (fieldsIt != flist->constEnd() && (it != values.end())) { | 1087 | while (fieldsIt != flist->constEnd() && (it != values.end())) { | ||
1088 | KDbField *f = *fieldsIt; | 1088 | KDbField *f = *fieldsIt; | ||
1089 | if (sql.isEmpty()) { | 1089 | if (sql.isEmpty()) { | ||
1090 | sql = KDbEscapedString("INSERT INTO ") + escapeIdentifier(tableSchema->name()) | 1090 | sql = KDbEscapedString("INSERT INTO ") + escapeIdentifier(tableSchema->name()) | ||
1091 | + " VALUES ("; | 1091 | + " VALUES ("; | ||
1092 | } | 1092 | } | ||
1093 | else { | 1093 | else { | ||
1094 | sql += ','; | 1094 | sql += ','; | ||
1095 | } | 1095 | } | ||
1096 | sql += d->driver->valueToSQL(f, *it); | 1096 | sql += d->driver->valueToSQL(f, *it); | ||
1097 | // kdbDebug() << "val" << i++ << ": " << d->driver->valueToSQL( f, *it ); | 1097 | // kdbDebug() << "val" << i++ << ": " << d->driver->valueToSQL( f, *it ); | ||
1098 | ++it; | 1098 | ++it; | ||
1099 | ++fieldsIt; | 1099 | ++fieldsIt; | ||
1100 | } | 1100 | } | ||
1101 | sql += ')'; | 1101 | sql += ')'; | ||
1102 | m_result.setSql(sql); | 1102 | m_result.setSql(sql); | ||
1103 | return insertRecordInternal(tableSchema->name(), tableSchema, sql, result); | 1103 | res = insertRecordInternal(tableSchema->name(), tableSchema, sql); | ||
1104 | return res; | ||||
1104 | } | 1105 | } | ||
1105 | 1106 | | |||
1106 | bool KDbConnection::insertRecord(KDbFieldList* fields, const QList<QVariant>& values, | 1107 | QSharedPointer<KDbSqlResult> KDbConnection::insertRecord(KDbFieldList *fields, | ||
1107 | KDbSqlResult** result) | 1108 | const QList<QVariant> &values) | ||
1108 | { | 1109 | { | ||
1109 | // Each SQL identifier needs to be escaped in the generated query. | 1110 | // Each SQL identifier needs to be escaped in the generated query. | ||
1111 | QSharedPointer<KDbSqlResult> res; | ||||
1110 | const KDbField::List *flist = fields->fields(); | 1112 | const KDbField::List *flist = fields->fields(); | ||
1111 | if (flist->isEmpty()) { | 1113 | if (flist->isEmpty()) { | ||
1112 | return false; | 1114 | return res; | ||
1113 | } | 1115 | } | ||
1114 | KDbField::ListIterator fieldsIt(flist->constBegin()); | 1116 | KDbField::ListIterator fieldsIt(flist->constBegin()); | ||
1115 | KDbEscapedString sql; | 1117 | KDbEscapedString sql; | ||
1116 | sql.reserve(4096); | 1118 | sql.reserve(4096); | ||
1117 | QList<QVariant>::ConstIterator it = values.constBegin(); | 1119 | QList<QVariant>::ConstIterator it = values.constBegin(); | ||
1118 | const QString tableName(flist->first()->table()->name()); | 1120 | const QString tableName(flist->first()->table()->name()); | ||
1119 | while (fieldsIt != flist->constEnd() && it != values.constEnd()) { | 1121 | while (fieldsIt != flist->constEnd() && it != values.constEnd()) { | ||
1120 | KDbField *f = *fieldsIt; | 1122 | KDbField *f = *fieldsIt; | ||
1121 | if (sql.isEmpty()) { | 1123 | if (sql.isEmpty()) { | ||
1122 | sql = KDbEscapedString("INSERT INTO ") + escapeIdentifier(tableName) + '(' + | 1124 | sql = KDbEscapedString("INSERT INTO ") + escapeIdentifier(tableName) + '(' + | ||
1123 | fields->sqlFieldsList(this) + ") VALUES ("; | 1125 | fields->sqlFieldsList(this) + ") VALUES ("; | ||
1124 | } | 1126 | } | ||
1125 | else { | 1127 | else { | ||
1126 | sql += ','; | 1128 | sql += ','; | ||
1127 | } | 1129 | } | ||
1128 | sql += d->driver->valueToSQL(f, *it); | 1130 | sql += d->driver->valueToSQL(f, *it); | ||
1129 | // kdbDebug() << "val" << i++ << ": " << d->driver->valueToSQL( f, *it ); | 1131 | // kdbDebug() << "val" << i++ << ": " << d->driver->valueToSQL( f, *it ); | ||
1130 | ++it; | 1132 | ++it; | ||
1131 | ++fieldsIt; | 1133 | ++fieldsIt; | ||
1132 | if (fieldsIt == flist->constEnd()) | 1134 | if (fieldsIt == flist->constEnd()) | ||
1133 | break; | 1135 | break; | ||
1134 | } | 1136 | } | ||
1135 | sql += ')'; | 1137 | sql += ')'; | ||
1136 | m_result.setSql(sql); | 1138 | m_result.setSql(sql); | ||
1137 | return insertRecordInternal(tableName, fields, sql, result); | 1139 | res = insertRecordInternal(tableName, fields, sql); | ||
1140 | return res; | ||||
1138 | } | 1141 | } | ||
1139 | 1142 | | |||
1140 | inline static bool checkSql(const KDbEscapedString& sql, KDbResult* result) | 1143 | inline static bool checkSql(const KDbEscapedString& sql, KDbResult* result) | ||
1141 | { | 1144 | { | ||
1142 | Q_ASSERT(result); | 1145 | Q_ASSERT(result); | ||
1143 | if (!sql.isValid()) { | 1146 | if (!sql.isValid()) { | ||
1144 | *result = KDbResult(ERR_SQL_EXECUTION_ERROR, | 1147 | *result = KDbResult(ERR_SQL_EXECUTION_ERROR, | ||
1145 | KDbConnection::tr("SQL statement for execution is invalid or empty.")); | 1148 | KDbConnection::tr("SQL statement for execution is invalid or empty.")); | ||
1146 | result->setErrorSql(sql); //remember for error handling | 1149 | result->setErrorSql(sql); //remember for error handling | ||
1147 | return false; | 1150 | return false; | ||
1148 | } | 1151 | } | ||
1149 | return true; | 1152 | return true; | ||
1150 | } | 1153 | } | ||
1151 | 1154 | | |||
1152 | KDbSqlResult* KDbConnection::executeSQL(const KDbEscapedString& sql) | 1155 | QSharedPointer<KDbSqlResult> KDbConnection::prepareSql(const KDbEscapedString& sql) | ||
1153 | { | 1156 | { | ||
1154 | m_result.setSql(sql); | 1157 | m_result.setSql(sql); | ||
1155 | return drv_executeSQL(sql); | 1158 | return QSharedPointer<KDbSqlResult>(drv_prepareSql(sql)); | ||
1156 | } | 1159 | } | ||
1157 | 1160 | | |||
1158 | bool KDbConnection::executeVoidSQL(const KDbEscapedString& sql) | 1161 | bool KDbConnection::executeSql(const KDbEscapedString& sql) | ||
1159 | { | 1162 | { | ||
1160 | m_result.setSql(sql); | 1163 | m_result.setSql(sql); | ||
1161 | if (!checkSql(sql, &m_result)) { | 1164 | if (!checkSql(sql, &m_result)) { | ||
1162 | return false; | 1165 | return false; | ||
1163 | } | 1166 | } | ||
1164 | if (!drv_executeVoidSQL(sql)) { | 1167 | if (!drv_executeSql(sql)) { | ||
1165 | m_result.setMessage(QString()); //clear as this could be most probably just "Unknown error" string. | 1168 | m_result.setMessage(QString()); //clear as this could be most probably just "Unknown error" string. | ||
1166 | m_result.setErrorSql(sql); | 1169 | m_result.setErrorSql(sql); | ||
1167 | m_result.prependMessage(ERR_SQL_EXECUTION_ERROR, | 1170 | m_result.prependMessage(ERR_SQL_EXECUTION_ERROR, | ||
1168 | tr("Error while executing SQL statement.")); | 1171 | tr("Error while executing SQL statement.")); | ||
1169 | qWarning() << m_result; | 1172 | qWarning() << m_result; | ||
1170 | return false; | 1173 | return false; | ||
1171 | } | 1174 | } | ||
1172 | return true; | 1175 | return true; | ||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Line(s) | 1254 | if (first) | |||
1252 | first = false; | 1255 | first = false; | ||
1253 | ++valsIt; | 1256 | ++valsIt; | ||
1254 | } | 1257 | } | ||
1255 | delete fl; | 1258 | delete fl; | ||
1256 | 1259 | | |||
1257 | sql.append(KDbEscapedString(" WHERE t_id=%1 AND f_name=%2") | 1260 | sql.append(KDbEscapedString(" WHERE t_id=%1 AND f_name=%2") | ||
1258 | .arg(d->driver->valueToSQL(KDbField::Integer, field->table()->id())) | 1261 | .arg(d->driver->valueToSQL(KDbField::Integer, field->table()->id())) | ||
1259 | .arg(escapeString(field->name()))); | 1262 | .arg(escapeString(field->name()))); | ||
1260 | return executeVoidSQL(sql); | 1263 | return executeSql(sql); | ||
1261 | } | 1264 | } | ||
1262 | 1265 | | |||
1263 | #define createTable_ERR \ | 1266 | #define createTable_ERR \ | ||
1264 | { kdbDebug() << "ERROR!"; \ | 1267 | { kdbDebug() << "ERROR!"; \ | ||
1265 | m_result.prependMessage(KDbConnection::tr("Creating table failed.")); \ | 1268 | m_result.prependMessage(KDbConnection::tr("Creating table failed.")); \ | ||
1266 | rollbackAutoCommitTransaction(tg.transaction()); \ | 1269 | rollbackAutoCommitTransaction(tg.transaction()); \ | ||
1267 | return false; } | 1270 | return false; } | ||
1268 | 1271 | | |||
▲ Show 20 Lines • Show All 158 Lines • ▼ Show 20 Line(s) | |||||
1427 | } | 1430 | } | ||
1428 | 1431 | | |||
1429 | bool KDbConnection::drv_copyTableData(const KDbTableSchema &tableSchema, | 1432 | bool KDbConnection::drv_copyTableData(const KDbTableSchema &tableSchema, | ||
1430 | const KDbTableSchema &destinationTableSchema) | 1433 | const KDbTableSchema &destinationTableSchema) | ||
1431 | { | 1434 | { | ||
1432 | KDbEscapedString sql = KDbEscapedString("INSERT INTO %1 SELECT * FROM %2") | 1435 | KDbEscapedString sql = KDbEscapedString("INSERT INTO %1 SELECT * FROM %2") | ||
1433 | .arg(escapeIdentifier(destinationTableSchema.name())) | 1436 | .arg(escapeIdentifier(destinationTableSchema.name())) | ||
1434 | .arg(escapeIdentifier(tableSchema.name())); | 1437 | .arg(escapeIdentifier(tableSchema.name())); | ||
1435 | return executeVoidSQL(sql); | 1438 | return executeSql(sql); | ||
1436 | } | 1439 | } | ||
1437 | 1440 | | |||
1438 | bool KDbConnection::removeObject(int objId) | 1441 | bool KDbConnection::removeObject(int objId) | ||
1439 | { | 1442 | { | ||
1440 | clearResult(); | 1443 | clearResult(); | ||
1441 | //remove table schema from kexi__* tables | 1444 | //remove table schema from kexi__* tables | ||
1442 | KDbTableSchema *kexi__objects = d->table(QLatin1String("kexi__objects")); | 1445 | KDbTableSchema *kexi__objects = d->table(QLatin1String("kexi__objects")); | ||
1443 | KDbTableSchema *kexi__objectdata = d->table(QLatin1String("kexi__objectdata")); | 1446 | KDbTableSchema *kexi__objectdata = d->table(QLatin1String("kexi__objectdata")); | ||
1444 | if (!kexi__objects || !kexi__objectdata | 1447 | if (!kexi__objects || !kexi__objectdata | ||
1445 | || !KDb::deleteRecords(this, *kexi__objects, QLatin1String("o_id"), objId) //schema entry | 1448 | || !KDb::deleteRecords(this, *kexi__objects, QLatin1String("o_id"), objId) //schema entry | ||
1446 | || !KDb::deleteRecords(this, *kexi__objectdata, QLatin1String("o_id"), objId)) //data blocks | 1449 | || !KDb::deleteRecords(this, *kexi__objectdata, QLatin1String("o_id"), objId)) //data blocks | ||
1447 | { | 1450 | { | ||
1448 | m_result = KDbResult(ERR_DELETE_SERVER_ERROR, | 1451 | m_result = KDbResult(ERR_DELETE_SERVER_ERROR, | ||
1449 | tr("Could not delete object's data.")); | 1452 | tr("Could not delete object's data.")); | ||
1450 | return false; | 1453 | return false; | ||
1451 | } | 1454 | } | ||
1452 | return true; | 1455 | return true; | ||
1453 | } | 1456 | } | ||
1454 | 1457 | | |||
1455 | bool KDbConnection::drv_dropTable(const QString& tableName) | 1458 | bool KDbConnection::drv_dropTable(const QString& tableName) | ||
1456 | { | 1459 | { | ||
1457 | return executeVoidSQL(KDbEscapedString("DROP TABLE %1").arg(escapeIdentifier(tableName))); | 1460 | return executeSql(KDbEscapedString("DROP TABLE %1").arg(escapeIdentifier(tableName))); | ||
1458 | } | 1461 | } | ||
1459 | 1462 | | |||
1460 | tristate KDbConnection::dropTable(KDbTableSchema* tableSchema) | 1463 | tristate KDbConnection::dropTable(KDbTableSchema* tableSchema) | ||
1461 | { | 1464 | { | ||
1462 | return dropTable(tableSchema, true); | 1465 | return dropTable(tableSchema, true); | ||
1463 | } | 1466 | } | ||
1464 | 1467 | | |||
1465 | tristate KDbConnection::dropTable(KDbTableSchema* tableSchema, bool alsoRemoveSchema) | 1468 | tristate KDbConnection::dropTable(KDbTableSchema* tableSchema, bool alsoRemoveSchema) | ||
▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Line(s) | 1606 | #define alterTableName_ERR \ | |||
1609 | 1612 | | |||
1610 | // drop the table replaced (with schema) | 1613 | // drop the table replaced (with schema) | ||
1611 | if (destTableExists) { | 1614 | if (destTableExists) { | ||
1612 | if (!dropTable(newName)) { | 1615 | if (!dropTable(newName)) { | ||
1613 | return false; | 1616 | return false; | ||
1614 | } | 1617 | } | ||
1615 | 1618 | | |||
1616 | // the new table owns the previous table's id: | 1619 | // the new table owns the previous table's id: | ||
1617 | if (!executeVoidSQL( | 1620 | if (!executeSql( | ||
1618 | KDbEscapedString("UPDATE kexi__objects SET o_id=%1 WHERE o_id=%2 AND o_type=%3") | 1621 | KDbEscapedString("UPDATE kexi__objects SET o_id=%1 WHERE o_id=%2 AND o_type=%3") | ||
1619 | .arg(d->driver->valueToSQL(KDbField::Integer, origID)) | 1622 | .arg(d->driver->valueToSQL(KDbField::Integer, origID)) | ||
1620 | .arg(d->driver->valueToSQL(KDbField::Integer, tableSchema->id())) | 1623 | .arg(d->driver->valueToSQL(KDbField::Integer, tableSchema->id())) | ||
1621 | .arg(d->driver->valueToSQL(KDbField::Integer, int(KDb::TableObjectType))))) | 1624 | .arg(d->driver->valueToSQL(KDbField::Integer, int(KDb::TableObjectType))))) | ||
1622 | { | 1625 | { | ||
1623 | return false; | 1626 | return false; | ||
1624 | } | 1627 | } | ||
1625 | if (!executeVoidSQL(KDbEscapedString("UPDATE kexi__fields SET t_id=%1 WHERE t_id=%2") | 1628 | if (!executeSql(KDbEscapedString("UPDATE kexi__fields SET t_id=%1 WHERE t_id=%2") | ||
1626 | .arg(d->driver->valueToSQL(KDbField::Integer, origID)) | 1629 | .arg(d->driver->valueToSQL(KDbField::Integer, origID)) | ||
1627 | .arg(d->driver->valueToSQL(KDbField::Integer, tableSchema->id())))) | 1630 | .arg(d->driver->valueToSQL(KDbField::Integer, tableSchema->id())))) | ||
1628 | { | 1631 | { | ||
1629 | return false; | 1632 | return false; | ||
1630 | } | 1633 | } | ||
1631 | 1634 | | |||
1632 | //maintain table ID | 1635 | //maintain table ID | ||
1633 | d->changeTableId(tableSchema, origID); | 1636 | d->changeTableId(tableSchema, origID); | ||
1634 | tableSchema->setId(origID); | 1637 | tableSchema->setId(origID); | ||
1635 | } | 1638 | } | ||
1636 | 1639 | | |||
1637 | if (!drv_alterTableName(tableSchema, newTableName)) { | 1640 | if (!drv_alterTableName(tableSchema, newTableName)) { | ||
1638 | alterTableName_ERR; | 1641 | alterTableName_ERR; | ||
1639 | return false; | 1642 | return false; | ||
1640 | } | 1643 | } | ||
1641 | 1644 | | |||
1642 | // Update kexi__objects | 1645 | // Update kexi__objects | ||
1643 | //! @todo | 1646 | //! @todo | ||
1644 | if (!executeVoidSQL(KDbEscapedString("UPDATE kexi__objects SET o_name=%1 WHERE o_id=%2") | 1647 | if (!executeSql(KDbEscapedString("UPDATE kexi__objects SET o_name=%1 WHERE o_id=%2") | ||
1645 | .arg(escapeString(tableSchema->name())) | 1648 | .arg(escapeString(tableSchema->name())) | ||
1646 | .arg(d->driver->valueToSQL(KDbField::Integer, tableSchema->id())))) | 1649 | .arg(d->driver->valueToSQL(KDbField::Integer, tableSchema->id())))) | ||
1647 | { | 1650 | { | ||
1648 | alterTableName_ERR; | 1651 | alterTableName_ERR; | ||
1649 | return false; | 1652 | return false; | ||
1650 | } | 1653 | } | ||
1651 | //! @todo what about caption? | 1654 | //! @todo what about caption? | ||
1652 | 1655 | | |||
Show All 10 Lines | |||||
1663 | return true; | 1666 | return true; | ||
1664 | } | 1667 | } | ||
1665 | 1668 | | |||
1666 | bool KDbConnection::drv_alterTableName(KDbTableSchema* tableSchema, const QString& newName) | 1669 | bool KDbConnection::drv_alterTableName(KDbTableSchema* tableSchema, const QString& newName) | ||
1667 | { | 1670 | { | ||
1668 | const QString oldTableName = tableSchema->name(); | 1671 | const QString oldTableName = tableSchema->name(); | ||
1669 | tableSchema->setName(newName); | 1672 | tableSchema->setName(newName); | ||
1670 | 1673 | | |||
1671 | if (!executeVoidSQL(KDbEscapedString("ALTER TABLE %1 RENAME TO %2") | 1674 | if (!executeSql(KDbEscapedString("ALTER TABLE %1 RENAME TO %2") | ||
1672 | .arg(KDbEscapedString(escapeIdentifier(oldTableName)), | 1675 | .arg(KDbEscapedString(escapeIdentifier(oldTableName)), | ||
1673 | KDbEscapedString(escapeIdentifier(newName))))) | 1676 | KDbEscapedString(escapeIdentifier(newName))))) | ||
1674 | { | 1677 | { | ||
1675 | tableSchema->setName(oldTableName); //restore old name | 1678 | tableSchema->setName(oldTableName); //restore old name | ||
1676 | return false; | 1679 | return false; | ||
1677 | } | 1680 | } | ||
1678 | return true; | 1681 | return true; | ||
1679 | } | 1682 | } | ||
Show All 33 Lines | |||||
1713 | bool KDbConnection::drv_createTable(const KDbTableSchema& tableSchema) | 1716 | bool KDbConnection::drv_createTable(const KDbTableSchema& tableSchema) | ||
1714 | { | 1717 | { | ||
1715 | const KDbNativeStatementBuilder builder(this); | 1718 | const KDbNativeStatementBuilder builder(this); | ||
1716 | KDbEscapedString sql; | 1719 | KDbEscapedString sql; | ||
1717 | if (!builder.generateCreateTableStatement(&sql,tableSchema)) { | 1720 | if (!builder.generateCreateTableStatement(&sql,tableSchema)) { | ||
1718 | return false; | 1721 | return false; | ||
1719 | } | 1722 | } | ||
1720 | //kdbDebug() << "******** " << sql; | 1723 | //kdbDebug() << "******** " << sql; | ||
1721 | return executeVoidSQL(sql); | 1724 | return executeSql(sql); | ||
1722 | } | 1725 | } | ||
1723 | 1726 | | |||
1724 | bool KDbConnection::drv_createTable(const QString& tableName) | 1727 | bool KDbConnection::drv_createTable(const QString& tableName) | ||
1725 | { | 1728 | { | ||
1726 | KDbTableSchema *ts = tableSchema(tableName); | 1729 | KDbTableSchema *ts = tableSchema(tableName); | ||
1727 | if (!ts) | 1730 | if (!ts) | ||
1728 | return false; | 1731 | return false; | ||
1729 | return drv_createTable(*ts); | 1732 | return drv_createTable(*ts); | ||
▲ Show 20 Lines • Show All 209 Lines • ▼ Show 20 Line(s) | 1939 | { | |||
1939 | if (!drv_setAutoCommit(on)) | 1942 | if (!drv_setAutoCommit(on)) | ||
1940 | return false; | 1943 | return false; | ||
1941 | d->autoCommit = on; | 1944 | d->autoCommit = on; | ||
1942 | return true; | 1945 | return true; | ||
1943 | } | 1946 | } | ||
1944 | 1947 | | |||
1945 | KDbTransactionData* KDbConnection::drv_beginTransaction() | 1948 | KDbTransactionData* KDbConnection::drv_beginTransaction() | ||
1946 | { | 1949 | { | ||
1947 | if (!executeVoidSQL(KDbEscapedString("BEGIN"))) | 1950 | if (!executeSql(KDbEscapedString("BEGIN"))) | ||
1948 | return nullptr; | 1951 | return nullptr; | ||
1949 | return new KDbTransactionData(this); | 1952 | return new KDbTransactionData(this); | ||
1950 | } | 1953 | } | ||
1951 | 1954 | | |||
1952 | bool KDbConnection::drv_commitTransaction(KDbTransactionData *) | 1955 | bool KDbConnection::drv_commitTransaction(KDbTransactionData *) | ||
1953 | { | 1956 | { | ||
1954 | return executeVoidSQL(KDbEscapedString("COMMIT")); | 1957 | return executeSql(KDbEscapedString("COMMIT")); | ||
1955 | } | 1958 | } | ||
1956 | 1959 | | |||
1957 | bool KDbConnection::drv_rollbackTransaction(KDbTransactionData *) | 1960 | bool KDbConnection::drv_rollbackTransaction(KDbTransactionData *) | ||
1958 | { | 1961 | { | ||
1959 | return executeVoidSQL(KDbEscapedString("ROLLBACK")); | 1962 | return executeSql(KDbEscapedString("ROLLBACK")); | ||
1960 | } | 1963 | } | ||
1961 | 1964 | | |||
1962 | bool KDbConnection::drv_setAutoCommit(bool /*on*/) | 1965 | bool KDbConnection::drv_setAutoCommit(bool /*on*/) | ||
1963 | { | 1966 | { | ||
1964 | return true; | 1967 | return true; | ||
1965 | } | 1968 | } | ||
1966 | 1969 | | |||
1967 | KDbCursor* KDbConnection::executeQuery(const KDbEscapedString& sql, KDbCursor::Options options) | 1970 | KDbCursor* KDbConnection::executeQuery(const KDbEscapedString& sql, KDbCursor::Options options) | ||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Line(s) | 2091 | { | |||
2104 | } | 2107 | } | ||
2105 | if (newObject) { | 2108 | if (newObject) { | ||
2106 | if (object->id() <= 0) {//get new ID | 2109 | if (object->id() <= 0) {//get new ID | ||
2107 | QScopedPointer<KDbFieldList> fl(ts->subList( | 2110 | QScopedPointer<KDbFieldList> fl(ts->subList( | ||
2108 | QList<QByteArray>() << "o_type" << "o_name" << "o_caption" << "o_desc")); | 2111 | QList<QByteArray>() << "o_type" << "o_name" << "o_caption" << "o_desc")); | ||
2109 | if (!fl) { | 2112 | if (!fl) { | ||
2110 | return false; | 2113 | return false; | ||
2111 | } | 2114 | } | ||
2112 | KDbSqlResult* result; | 2115 | QSharedPointer<KDbSqlResult> result | ||
2113 | if (!insertRecord(fl.data(), QVariant(object->type()), QVariant(object->name()), | 2116 | = insertRecord(fl.data(), QVariant(object->type()), QVariant(object->name()), | ||
2114 | QVariant(object->caption()), QVariant(object->description()), &result)) | 2117 | QVariant(object->caption()), QVariant(object->description())); | ||
2115 | { | 2118 | if (!result) { | ||
2116 | return false; | 2119 | return false; | ||
2117 | } | 2120 | } | ||
2118 | QScopedPointer<KDbSqlResult> resultGuard(result); | | |||
2119 | //fetch newly assigned ID | 2121 | //fetch newly assigned ID | ||
2120 | //! @todo safe to cast it? | 2122 | //! @todo safe to cast it? | ||
2121 | quint64 obj_id = KDb::lastInsertedAutoIncValue(result, QLatin1String("o_id"), *ts); | 2123 | quint64 obj_id = KDb::lastInsertedAutoIncValue(result, QLatin1String("o_id"), *ts); | ||
2122 | //kdbDebug() << "NEW obj_id == " << obj_id; | 2124 | //kdbDebug() << "NEW obj_id == " << obj_id; | ||
2123 | if (obj_id == std::numeric_limits<quint64>::max()) { | 2125 | if (obj_id == std::numeric_limits<quint64>::max()) { | ||
2124 | return false; | 2126 | return false; | ||
2125 | } | 2127 | } | ||
2126 | object->setId(obj_id); | 2128 | object->setId(obj_id); | ||
2127 | return true; | 2129 | return true; | ||
2128 | } else { | 2130 | } else { | ||
2129 | QScopedPointer<KDbFieldList> fl(ts->subList( | 2131 | QScopedPointer<KDbFieldList> fl(ts->subList( | ||
2130 | QList<QByteArray>() << "o_id" << "o_type" << "o_name" << "o_caption" << "o_desc")); | 2132 | QList<QByteArray>() << "o_id" << "o_type" << "o_name" << "o_caption" << "o_desc")); | ||
2131 | return fl && insertRecord(fl.data(), QVariant(object->id()), QVariant(object->type()), | 2133 | return fl && insertRecord(fl.data(), QVariant(object->id()), QVariant(object->type()), | ||
2132 | QVariant(object->name()), QVariant(object->caption()), | 2134 | QVariant(object->name()), QVariant(object->caption()), | ||
2133 | QVariant(object->description())); | 2135 | QVariant(object->description())); | ||
2134 | } | 2136 | } | ||
2135 | } | 2137 | } | ||
2136 | //existing object: | 2138 | //existing object: | ||
2137 | return executeVoidSQL( | 2139 | return executeSql( | ||
2138 | KDbEscapedString("UPDATE kexi__objects SET o_type=%2, o_caption=%3, o_desc=%4 WHERE o_id=%1") | 2140 | KDbEscapedString("UPDATE kexi__objects SET o_type=%2, o_caption=%3, o_desc=%4 WHERE o_id=%1") | ||
2139 | .arg(d->driver->valueToSQL(KDbField::Integer, object->id())) | 2141 | .arg(d->driver->valueToSQL(KDbField::Integer, object->id())) | ||
2140 | .arg(d->driver->valueToSQL(KDbField::Integer, object->type())) | 2142 | .arg(d->driver->valueToSQL(KDbField::Integer, object->type())) | ||
2141 | .arg(escapeString(object->caption())) | 2143 | .arg(escapeString(object->caption())) | ||
2142 | .arg(escapeString(object->description()))); | 2144 | .arg(escapeString(object->description()))); | ||
2143 | } | 2145 | } | ||
2144 | 2146 | | |||
2145 | bool KDbConnection::storeObjectData(KDbObject* object) | 2147 | bool KDbConnection::storeObjectData(KDbObject* object) | ||
▲ Show 20 Lines • Show All 702 Lines • ▼ Show 20 Line(s) | 2844 | { | |||
2848 | KDbEscapedString sql_sub(KDb::sqlWhere(d->driver, KDbField::Text, QLatin1String("o_sub_id"), | 2850 | KDbEscapedString sql_sub(KDb::sqlWhere(d->driver, KDbField::Text, QLatin1String("o_sub_id"), | ||
2849 | dataID.isEmpty() ? QVariant() : QVariant(dataID))); | 2851 | dataID.isEmpty() ? QVariant() : QVariant(dataID))); | ||
2850 | 2852 | | |||
2851 | const tristate result = resultExists(sql + " AND " + sql_sub); | 2853 | const tristate result = resultExists(sql + " AND " + sql_sub); | ||
2852 | if (~result) { | 2854 | if (~result) { | ||
2853 | return false; | 2855 | return false; | ||
2854 | } | 2856 | } | ||
2855 | if (result == true) { | 2857 | if (result == true) { | ||
2856 | return executeVoidSQL(KDbEscapedString("UPDATE kexi__objectdata SET o_data=%1 WHERE o_id=%2 AND ") | 2858 | return executeSql(KDbEscapedString("UPDATE kexi__objectdata SET o_data=%1 WHERE o_id=%2 AND ") | ||
2857 | .arg(d->driver->valueToSQL(KDbField::LongText, dataString)) | 2859 | .arg(d->driver->valueToSQL(KDbField::LongText, dataString)) | ||
2858 | .arg(d->driver->valueToSQL(KDbField::Integer, objectID)) | 2860 | .arg(d->driver->valueToSQL(KDbField::Integer, objectID)) | ||
2859 | + sql_sub); | 2861 | + sql_sub); | ||
2860 | } | 2862 | } | ||
2861 | return executeVoidSQL( | 2863 | return executeSql( | ||
2862 | KDbEscapedString("INSERT INTO kexi__objectdata (o_id, o_data, o_sub_id) VALUES (") | 2864 | KDbEscapedString("INSERT INTO kexi__objectdata (o_id, o_data, o_sub_id) VALUES (") | ||
2863 | + KDbEscapedString::number(objectID) + ',' + d->driver->valueToSQL(KDbField::LongText, dataString) | 2865 | + KDbEscapedString::number(objectID) + ',' + d->driver->valueToSQL(KDbField::LongText, dataString) | ||
2864 | + ',' + d->driver->valueToSQL(KDbField::Text, dataID) + ')'); | 2866 | + ',' + d->driver->valueToSQL(KDbField::Text, dataID) + ')'); | ||
2865 | } | 2867 | } | ||
2866 | 2868 | | |||
2867 | bool KDbConnection::copyDataBlock(int sourceObjectID, int destObjectID, const QString &dataID) | 2869 | bool KDbConnection::copyDataBlock(int sourceObjectID, int destObjectID, const QString &dataID) | ||
2868 | { | 2870 | { | ||
2869 | if (sourceObjectID <= 0 || destObjectID <= 0) | 2871 | if (sourceObjectID <= 0 || destObjectID <= 0) | ||
2870 | return false; | 2872 | return false; | ||
2871 | if (sourceObjectID == destObjectID) | 2873 | if (sourceObjectID == destObjectID) | ||
2872 | return true; | 2874 | return true; | ||
2873 | if (!removeDataBlock(destObjectID, dataID)) // remove before copying | 2875 | if (!removeDataBlock(destObjectID, dataID)) // remove before copying | ||
2874 | return false; | 2876 | return false; | ||
2875 | KDbEscapedString sql = KDbEscapedString( | 2877 | KDbEscapedString sql = KDbEscapedString( | ||
2876 | "INSERT INTO kexi__objectdata SELECT %1, t.o_data, t.o_sub_id " | 2878 | "INSERT INTO kexi__objectdata SELECT %1, t.o_data, t.o_sub_id " | ||
2877 | "FROM kexi__objectdata AS t WHERE o_id=%2") | 2879 | "FROM kexi__objectdata AS t WHERE o_id=%2") | ||
2878 | .arg(d->driver->valueToSQL(KDbField::Integer, destObjectID)) | 2880 | .arg(d->driver->valueToSQL(KDbField::Integer, destObjectID)) | ||
2879 | .arg(d->driver->valueToSQL(KDbField::Integer, sourceObjectID)); | 2881 | .arg(d->driver->valueToSQL(KDbField::Integer, sourceObjectID)); | ||
2880 | if (!dataID.isEmpty()) { | 2882 | if (!dataID.isEmpty()) { | ||
2881 | sql += KDbEscapedString(" AND ") + KDb::sqlWhere(d->driver, KDbField::Text, | 2883 | sql += KDbEscapedString(" AND ") + KDb::sqlWhere(d->driver, KDbField::Text, | ||
2882 | QLatin1String("o_sub_id"), dataID); | 2884 | QLatin1String("o_sub_id"), dataID); | ||
2883 | } | 2885 | } | ||
2884 | return executeVoidSQL(sql); | 2886 | return executeSql(sql); | ||
2885 | } | 2887 | } | ||
2886 | 2888 | | |||
2887 | bool KDbConnection::removeDataBlock(int objectID, const QString& dataID) | 2889 | bool KDbConnection::removeDataBlock(int objectID, const QString& dataID) | ||
2888 | { | 2890 | { | ||
2889 | if (objectID <= 0) | 2891 | if (objectID <= 0) | ||
2890 | return false; | 2892 | return false; | ||
2891 | if (dataID.isEmpty()) | 2893 | if (dataID.isEmpty()) | ||
2892 | return KDb::deleteRecords(this, QLatin1String("kexi__objectdata"), | 2894 | return KDb::deleteRecords(this, QLatin1String("kexi__objectdata"), | ||
▲ Show 20 Lines • Show All 216 Lines • ▼ Show 20 Line(s) | 3057 | //! @todo perhaps we can try to update without using PKEY? | |||
3109 | } | 3111 | } | ||
3110 | sql += (sqlset + " WHERE " + sqlwhere); | 3112 | sql += (sqlset + " WHERE " + sqlwhere); | ||
3111 | //kdbDebug() << " -- SQL == " << ((sql.length() > 400) ? (sql.left(400) + "[.....]") : sql); | 3113 | //kdbDebug() << " -- SQL == " << ((sql.length() > 400) ? (sql.left(400) + "[.....]") : sql); | ||
3112 | 3114 | | |||
3113 | // preprocessing before update | 3115 | // preprocessing before update | ||
3114 | if (!drv_beforeUpdate(mt->name(), &affectedFields)) | 3116 | if (!drv_beforeUpdate(mt->name(), &affectedFields)) | ||
3115 | return false; | 3117 | return false; | ||
3116 | 3118 | | |||
3117 | bool res = executeVoidSQL(sql); | 3119 | bool res = executeSql(sql); | ||
3118 | 3120 | | |||
3119 | // postprocessing after update | 3121 | // postprocessing after update | ||
3120 | if (!drv_afterUpdate(mt->name(), &affectedFields)) | 3122 | if (!drv_afterUpdate(mt->name(), &affectedFields)) | ||
3121 | return false; | 3123 | return false; | ||
3122 | 3124 | | |||
3123 | if (!res) { | 3125 | if (!res) { | ||
3124 | m_result = KDbResult(ERR_UPDATE_SERVER_ERROR, | 3126 | m_result = KDbResult(ERR_UPDATE_SERVER_ERROR, | ||
3125 | tr("Record updating on the server failed.")); | 3127 | tr("Record updating on the server failed.")); | ||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Line(s) | 3219 | for (KDbRecordEditBuffer::DbHash::ConstIterator it = b.constBegin();it != b.constEnd();++it) { | |||
3227 | sqlcols += escapeIdentifier(currentField->name()); | 3229 | sqlcols += escapeIdentifier(currentField->name()); | ||
3228 | sqlvals += d->driver->valueToSQL(currentField, it.value()); | 3230 | sqlvals += d->driver->valueToSQL(currentField, it.value()); | ||
3229 | } | 3231 | } | ||
3230 | } | 3232 | } | ||
3231 | sql += (sqlcols + ") VALUES (" + sqlvals + ')'); | 3233 | sql += (sqlcols + ") VALUES (" + sqlvals + ')'); | ||
3232 | // kdbDebug() << " -- SQL == " << sql; | 3234 | // kdbDebug() << " -- SQL == " << sql; | ||
3233 | 3235 | | |||
3234 | // low-level insert | 3236 | // low-level insert | ||
3235 | KDbSqlResult* result; | 3237 | QSharedPointer<KDbSqlResult> result = insertRecordInternal(mt->name(), &affectedFields, sql); | ||
3236 | if (!insertRecordInternal(mt->name(), &affectedFields, sql, &result)) { | 3238 | if (!result) { | ||
3237 | m_result = KDbResult(ERR_INSERT_SERVER_ERROR, | 3239 | m_result = KDbResult(ERR_INSERT_SERVER_ERROR, | ||
3238 | tr("Record inserting on the server failed.")); | 3240 | tr("Record inserting on the server failed.")); | ||
3239 | return false; | 3241 | return false; | ||
3240 | } | 3242 | } | ||
3241 | //success: now also assign a new value in memory: | 3243 | //success: now also assign a new value in memory: | ||
3242 | QScopedPointer<KDbSqlResult> resultGuard(result); | | |||
3243 | QHash<KDbQueryColumnInfo*, int> columnsOrderExpanded; | 3244 | QHash<KDbQueryColumnInfo*, int> columnsOrderExpanded; | ||
3244 | updateRecordDataWithNewValues(query, data, b, &columnsOrderExpanded); | 3245 | updateRecordDataWithNewValues(query, data, b, &columnsOrderExpanded); | ||
3245 | 3246 | | |||
3246 | //fetch autoincremented values | 3247 | //fetch autoincremented values | ||
3247 | KDbQueryColumnInfo::List *aif_list = query->autoIncrementFields(); | 3248 | KDbQueryColumnInfo::List *aif_list = query->autoIncrementFields(); | ||
3248 | quint64 recordId = 0; | 3249 | quint64 recordId = 0; | ||
3249 | if (pkey && !aif_list->isEmpty()) { | 3250 | if (pkey && !aif_list->isEmpty()) { | ||
3250 | //! @todo now only if PKEY is present, this should also work when there's no PKEY | 3251 | //! @todo now only if PKEY is present, this should also work when there's no PKEY | ||
3251 | KDbQueryColumnInfo *id_columnInfo = aif_list->first(); | 3252 | KDbQueryColumnInfo *id_columnInfo = aif_list->first(); | ||
3252 | //! @todo safe to cast it? | 3253 | //! @todo safe to cast it? | ||
3253 | quint64 last_id = KDb::lastInsertedAutoIncValue(result, | 3254 | quint64 last_id | ||
3254 | id_columnInfo->field()->name(), id_columnInfo->field()->table()->name(), &recordId); | 3255 | = KDb::lastInsertedAutoIncValue(result, id_columnInfo->field()->name(), | ||
3256 | id_columnInfo->field()->table()->name(), &recordId); | ||||
3255 | if (last_id == std::numeric_limits<quint64>::max()) { | 3257 | if (last_id == std::numeric_limits<quint64>::max()) { | ||
3256 | //! @todo show error | 3258 | //! @todo show error | ||
3257 | //! @todo remove just inserted record. How? Using ROLLBACK? | 3259 | //! @todo remove just inserted record. How? Using ROLLBACK? | ||
3258 | return false; | 3260 | return false; | ||
3259 | } | 3261 | } | ||
3260 | KDbRecordData aif_data; | 3262 | KDbRecordData aif_data; | ||
3261 | KDbEscapedString getAutoIncForInsertedValue("SELECT " | 3263 | KDbEscapedString getAutoIncForInsertedValue("SELECT " | ||
3262 | + query->autoIncrementSQLFieldsList(this) | 3264 | + query->autoIncrementSQLFieldsList(this) | ||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Line(s) | 3341 | //js todo: pass the field's name somewhere! | |||
3345 | } | 3347 | } | ||
3346 | } else {//use RecordId | 3348 | } else {//use RecordId | ||
3347 | sqlwhere = KDbEscapedString(escapeIdentifier(d->driver->beh->ROW_ID_FIELD_NAME)) + '=' | 3349 | sqlwhere = KDbEscapedString(escapeIdentifier(d->driver->beh->ROW_ID_FIELD_NAME)) + '=' | ||
3348 | + d->driver->valueToSQL(KDbField::BigInteger, (*data)[data->size() - 1]); | 3350 | + d->driver->valueToSQL(KDbField::BigInteger, (*data)[data->size() - 1]); | ||
3349 | } | 3351 | } | ||
3350 | sql += sqlwhere; | 3352 | sql += sqlwhere; | ||
3351 | //kdbDebug() << " -- SQL == " << sql; | 3353 | //kdbDebug() << " -- SQL == " << sql; | ||
3352 | 3354 | | |||
3353 | if (!executeVoidSQL(sql)) { | 3355 | if (!executeSql(sql)) { | ||
3354 | m_result = KDbResult(ERR_DELETE_SERVER_ERROR, | 3356 | m_result = KDbResult(ERR_DELETE_SERVER_ERROR, | ||
3355 | tr("Record deletion on the server failed.")); | 3357 | tr("Record deletion on the server failed.")); | ||
3356 | return false; | 3358 | return false; | ||
3357 | } | 3359 | } | ||
3358 | return true; | 3360 | return true; | ||
3359 | } | 3361 | } | ||
3360 | 3362 | | |||
3361 | bool KDbConnection::deleteAllRecords(KDbQuerySchema* query) | 3363 | bool KDbConnection::deleteAllRecords(KDbQuerySchema* query) | ||
3362 | { | 3364 | { | ||
3363 | clearResult(); | 3365 | clearResult(); | ||
3364 | KDbTableSchema *mt = query->masterTable(); | 3366 | KDbTableSchema *mt = query->masterTable(); | ||
3365 | if (!mt) { | 3367 | if (!mt) { | ||
3366 | kdbWarning() << " -- NO MASTER TABLE!"; | 3368 | kdbWarning() << " -- NO MASTER TABLE!"; | ||
3367 | return false; | 3369 | return false; | ||
3368 | } | 3370 | } | ||
3369 | KDbIndexSchema *pkey = mt->primaryKey(); | 3371 | KDbIndexSchema *pkey = mt->primaryKey(); | ||
3370 | if (!pkey || pkey->fields()->isEmpty()) { | 3372 | if (!pkey || pkey->fields()->isEmpty()) { | ||
3371 | kdbWarning() << "-- WARNING: NO MASTER TABLE's PKEY"; | 3373 | kdbWarning() << "-- WARNING: NO MASTER TABLE's PKEY"; | ||
3372 | } | 3374 | } | ||
3373 | KDbEscapedString sql = KDbEscapedString("DELETE FROM ") + escapeIdentifier(mt->name()); | 3375 | KDbEscapedString sql = KDbEscapedString("DELETE FROM ") + escapeIdentifier(mt->name()); | ||
3374 | //kdbDebug() << "-- SQL == " << sql; | 3376 | //kdbDebug() << "-- SQL == " << sql; | ||
3375 | 3377 | | |||
3376 | if (!executeVoidSQL(sql)) { | 3378 | if (!executeSql(sql)) { | ||
3377 | m_result = KDbResult(ERR_DELETE_SERVER_ERROR, | 3379 | m_result = KDbResult(ERR_DELETE_SERVER_ERROR, | ||
3378 | tr("Record deletion on the server failed.")); | 3380 | tr("Record deletion on the server failed.")); | ||
3379 | return false; | 3381 | return false; | ||
3380 | } | 3382 | } | ||
3381 | return true; | 3383 | return true; | ||
3382 | } | 3384 | } | ||
3383 | 3385 | | |||
3384 | KDbConnectionOptions* KDbConnection::options() | 3386 | KDbConnectionOptions* KDbConnection::options() | ||
Show All 18 Lines | |||||
3403 | { | 3405 | { | ||
3404 | //! @todo move to ConnectionInterface just like we moved execute() and prepare() to KDbPreparedStatementInterface... | 3406 | //! @todo move to ConnectionInterface just like we moved execute() and prepare() to KDbPreparedStatementInterface... | ||
3405 | KDbPreparedStatementInterface *iface = prepareStatementInternal(); | 3407 | KDbPreparedStatementInterface *iface = prepareStatementInternal(); | ||
3406 | if (!iface) | 3408 | if (!iface) | ||
3407 | return KDbPreparedStatement(); | 3409 | return KDbPreparedStatement(); | ||
3408 | return KDbPreparedStatement(iface, type, fields, whereFieldNames); | 3410 | return KDbPreparedStatement(iface, type, fields, whereFieldNames); | ||
3409 | } | 3411 | } | ||
3410 | 3412 | | |||
3411 | KDbEscapedString KDbConnection::recentSQLString() const { | 3413 | KDbEscapedString KDbConnection::recentSqlString() const { | ||
3412 | return result().errorSql().isEmpty() ? m_result.sql() : result().errorSql(); | 3414 | return result().errorSql().isEmpty() ? m_result.sql() : result().errorSql(); | ||
3413 | } | 3415 | } | ||
3414 | 3416 | | |||
3415 | KDbEscapedString KDbConnection::escapeString(const QString& str) const | 3417 | KDbEscapedString KDbConnection::escapeString(const QString& str) const | ||
3416 | { | 3418 | { | ||
3417 | return d->driver->escapeString(str); | 3419 | return d->driver->escapeString(str); | ||
3418 | } | 3420 | } | ||
3419 | 3421 | | |||
3420 | //! @todo extraMessages | 3422 | //! @todo extraMessages | ||
3421 | #if 0 | 3423 | #if 0 | ||
3422 | static const char *extraMessages[] = { | 3424 | static const char *extraMessages[] = { | ||
3423 | QT_TRANSLATE_NOOP("KDbConnection", "Unknown error.") | 3425 | QT_TRANSLATE_NOOP("KDbConnection", "Unknown error.") | ||
3424 | }; | 3426 | }; | ||
3425 | #endif | 3427 | #endif |
Pointer is passed when argument can be optional i.e. nullptr, by reference when it can't be optional. Respecting this rule code base became cleaner.