|

楼主 |
发表于 2024-12-10 22:24:21
|
显示全部楼层
河北省秦皇岛市
有点儿小修改, 改了一下同步表的逻辑, 现已支持复合主键:
bool SqliteUtils::SyncTable(const QString& tableName, const QMap<QString, FieldDefinition>& fieldDefinitions) {
auto dbConnection = AcquireDBConnection();
if (!dbConnection) {
return false;
}
QSqlQuery sqlQuery(dbConnection->database());
sqlQuery.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = :tableName");
sqlQuery.bindValue(":tableName", tableName);
if (!sqlQuery.exec()) {
return false;
}
bool tableExists = sqlQuery.next();
if (!tableExists) {
QStringList fieldDefinitionList;
QStringList primaryKeys;
QString createTableSql = QString("CREATE TABLE %1 (").arg(tableName);
for (auto it = fieldDefinitions.constBegin(); it != fieldDefinitions.constEnd(); ++it) {
if (it.key() == "PRIMARY KEY") {
if (!it.value().defaultValue.isEmpty()) {
primaryKeys.append(it.value().defaultValue);
}
continue;
}
QString fieldSql = QString("%1 %2").arg(it.key(), it.value().fieldType);
if (it.value().notNull) {
fieldSql += " NOT NULL";
}
if (!it.value().defaultValue.isEmpty()) {
fieldSql += QString(" DEFAULT %1").arg(it.value().defaultValue);
}
if (it.value().isPrimaryKey) {
fieldSql += " PRIMARY KEY";
}
fieldDefinitionList.append(fieldSql);
}
if (!primaryKeys.isEmpty()) {
fieldDefinitionList.append(QString("PRIMARY KEY %1").arg(primaryKeys.join(", ")));
}
createTableSql += fieldDefinitionList.join(", ") + ")";
return sqlQuery.exec(createTableSql);
} else {
sqlQuery.prepare(QString("PRAGMA table_info(%1)").arg(tableName));
if (!sqlQuery.exec()) {
return false;
}
bool requireUpdate = false;
QMap<QString, QString> existingFieldTypes;
while (sqlQuery.next()) {
QString fieldName = sqlQuery.value(1).toString();
QString fieldType = sqlQuery.value(2).toString();
existingFieldTypes[fieldName] = fieldType;
if (!fieldDefinitions.contains(fieldName)) {
requireUpdate = true;
continue;
}
if (fieldDefinitions[fieldName].fieldType.toUpper() != fieldType.toUpper()) {
requireUpdate = true;
}
}
for (auto it = fieldDefinitions.constBegin(); it != fieldDefinitions.constEnd(); ++it) {
if (!existingFieldTypes.contains(it.key())) {
requireUpdate = true;
break;
}
}
if (requireUpdate) {
QString tempTableName = QString("%1_%2").arg(tableName).arg(QDateTime::currentMSecsSinceEpoch());
QStringList selectFields;
QStringList fieldDefinitionList;
QStringList primaryKeys;
QStringList actualFields;
QString createTempTableSql = QString("CREATE TABLE %1 (").arg(tempTableName);
for (auto it = fieldDefinitions.constBegin(); it != fieldDefinitions.constEnd(); ++it) {
if (it.key() == "PRIMARY KEY") {
if (!it.value().defaultValue.isEmpty()) {
primaryKeys.append(it.value().defaultValue);
}
continue;
}
actualFields.append(it.key());
QString fieldSql = QString("%1 %2").arg(it.key(), it.value().fieldType);
if (it.value().notNull) {
fieldSql += " NOT NULL";
}
if (!it.value().defaultValue.isEmpty()) {
fieldSql += QString(" DEFAULT %1").arg(it.value().defaultValue);
}
if (it.value().isPrimaryKey) {
fieldSql += " PRIMARY KEY";
}
fieldDefinitionList.append(fieldSql);
if (existingFieldTypes.contains(it.key())) {
if (it.value().fieldType.toUpper() == "INTEGER") {
selectFields.append(QString("CAST(ROUND(CASE WHEN %1 GLOB '*[0-9]*' THEN %1 ELSE 0 END) AS INTEGER) AS %1").arg(it.key()));
} else if (it.value().fieldType.toUpper() == "REAL") {
selectFields.append(QString("CAST(CASE WHEN %1 GLOB '*[0-9]*' THEN %1 ELSE 0 END AS REAL) AS %1").arg(it.key()));
} else if (it.value().fieldType.toUpper() == "TEXT") {
selectFields.append(QString("CAST(%1 AS TEXT) AS %1").arg(it.key()));
} else {
selectFields.append(it.key());
}
} else {
if (!it.value().defaultValue.isEmpty()) {
selectFields.append(QString("%1 AS %2").arg(it.value().defaultValue, it.key()));
} else {
selectFields.append("NULL AS " + it.key());
}
}
}
if (!primaryKeys.isEmpty()) {
fieldDefinitionList.append(QString("PRIMARY KEY %1").arg(primaryKeys.join(", ")));
}
createTempTableSql += fieldDefinitionList.join(", ") + ")";
if (!sqlQuery.exec(createTempTableSql)) {
return false;
}
QString copyDataSql = QString("INSERT INTO %1 (%2) SELECT %3 FROM %4").arg(tempTableName, actualFields.join(", "), selectFields.join(", "), tableName);
if (!sqlQuery.exec(copyDataSql)) {
return false;
}
QString dropTableSql = QString("DROP TABLE IF EXISTS %1").arg(tableName);
if (!sqlQuery.exec(dropTableSql)) {
return false;
}
QString renameTableSql = QString("ALTER TABLE %1 RENAME TO %2").arg(tempTableName, tableName);
return sqlQuery.exec(renameTableSql);
} else {
return true;
}
}
} |
|