model.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "model.h"
  2. CWF_BEGIN_NAMESPACE
  3. void Model::updateDB()
  4. {
  5. verifyDbTableExist();
  6. verifyDbFields();
  7. }
  8. void Model::build(const QMap<QString, QVariant> &selectCondition)
  9. {
  10. // Get the data from the db and populate the model with them
  11. const auto &properties = MetaClassParser(this, true).getAllPropertiesNames();
  12. const auto &propValueMap = basicOperation.build(name, selectCondition, properties);
  13. // Loop on all the prop value to update the current object
  14. for (const auto &it : propValueMap.toStdMap()) {
  15. setProperty(it.first.toStdString().c_str(), it.second);
  16. }
  17. // Depending on the content of propValueMap, we set the built flag to true or false.
  18. // If the db query failed then the list is empty here.
  19. built = !propValueMap.empty();
  20. }
  21. void Model::buildFromJson(const QJsonObject &json, bool withTableNamePrefix)
  22. {
  23. const QStringList &props = MetaClassParser(this, true).getAllPropertiesNames();
  24. // Loop on all props
  25. for (const auto &prop : props) {
  26. QString propName;
  27. if (withTableNamePrefix)
  28. propName = getTableName() + "_" + prop;
  29. else
  30. propName = prop;
  31. const QJsonValue &jsonValue = json.value(propName);
  32. if (jsonValue.isUndefined()) {
  33. built = false;
  34. break;
  35. }
  36. if (!jsonValue.isNull()) {
  37. if (!setProperty(prop.toStdString().c_str(), jsonValue.toVariant())) {
  38. qDebug() << prop << jsonValue;
  39. built = false;
  40. break;
  41. }
  42. }
  43. }
  44. }
  45. bool Model::save()
  46. {
  47. if (!preSaveCheck()) {
  48. return false;
  49. }
  50. const auto &currentDt = QDateTime::currentDateTime();
  51. if (id == -1) {
  52. this->setProperty("createdDateTime", currentDt.toString(dtFormat));
  53. setCreatedDt(currentDt);
  54. }
  55. this->setProperty("lastModifiedDateTime", currentDt.toString(dtFormat));
  56. setLastModifiedDt(currentDt);
  57. int id = basicOperation.save(name, computePropsMap(*this));
  58. setProperty("id", id);
  59. return id != -1;
  60. }
  61. void Model::customizeField(const QString &fieldName,
  62. const QVariant::Type &type,
  63. const QString &tableName) const
  64. {
  65. Q_UNUSED(fieldName)
  66. Q_UNUSED(type)
  67. Q_UNUSED(tableName)
  68. }
  69. void Model::verifyDbTableExist()
  70. {
  71. if (!basicOperation.isTableInDb("table_version")) {
  72. if (!basicOperation.createVersionTable()) {
  73. return;
  74. }
  75. }
  76. if (!basicOperation.isTableInDb(name)) {
  77. if (basicOperation.createTable(name)) {
  78. qInfo() << "Model::verifyDbTableExist:"
  79. << "Table " << name << " was successfuly created";
  80. }
  81. }
  82. }
  83. void Model::verifyDbFields()
  84. {
  85. MetaClassParser parser(this, true);
  86. auto dbChangedPerformed = false;
  87. const auto &fieldsFromDb = basicOperation.fields(name);
  88. const auto &fieldsFromObject = parser.getAllPropertiesNames();
  89. auto fieldsFromObjectTmp(fieldsFromObject);
  90. for (auto &f : fieldsFromObjectTmp)
  91. f = f.toLower();
  92. for (auto it = parser.props.begin(); it != parser.props.end(); ++it) {
  93. const auto &fieldName = it.key().second;
  94. auto existInDb = fieldsFromDb.contains(fieldName);
  95. if (!existInDb) {
  96. qInfo() << "Model::verifyDbFields:"
  97. << "In" << name << "the field" << fieldName
  98. << "is present in the object but was not found in database."
  99. << "We update the database.";
  100. dbChangedPerformed = true;
  101. const auto &propertyType = this->propertyType(fieldName);
  102. basicOperation.addFieldToTable(fieldName, propertyType, name);
  103. customizeField(fieldName, propertyType, name);
  104. }
  105. }
  106. // Security loop to check no field is missing
  107. for (const auto &fieldName : fieldsFromDb) {
  108. if (!fieldsFromObjectTmp.contains(fieldName.toLower())) {
  109. qDebug() << "Model::verifyDbFields: The field " << fieldName
  110. << "was present in the DB and not in the object."
  111. << "It was probably deleted from the object property recently. "
  112. << "This is forbidden: a property should never be deleted because of db "
  113. "consistency";
  114. qFatal("A property saved in the database was deleted");
  115. }
  116. }
  117. // If we performed a change in the db
  118. if (dbChangedPerformed) {
  119. qInfo() << "The database was modified to update the table" << name << "."
  120. << "We will update the version for this table.";
  121. auto tableVersion = basicOperation.tableVersion(name);
  122. tableVersion += 1;
  123. basicOperation.changeTableVersion(name, tableVersion);
  124. }
  125. }
  126. QMetaProperty Model::findProperty(const QString &propertyName)
  127. {
  128. QMetaProperty emptyProperty;
  129. auto found = MetaClassParser(this, true).findProperty(propertyName);
  130. if (QString(found.name()) == QString(emptyProperty.name())) {
  131. QString msg(QString("Model::findProperty: The property ") + propertyName
  132. + " was not found in " + name);
  133. qDebug() << msg;
  134. qFatal("Property should always be found here");
  135. }
  136. return found;
  137. }
  138. QMap<QString, QVariant> Model::computePropsMap(Model &model)
  139. {
  140. QMap<QString, QVariant> propsMap;
  141. const auto &properties = MetaClassParser(this, true).getAllPropertiesNames();
  142. for (const auto &propName : properties) {
  143. const auto &prop = model.findProperty(propName);
  144. const auto &value = prop.read(&model);
  145. if (!value.isValid()) {
  146. qDebug() << "**** Error *****";
  147. qDebug() << "Model::computePropsMap: propName invalid: " << propName;
  148. qDebug() << "***************";
  149. }
  150. propsMap[propName] = value;
  151. }
  152. return propsMap;
  153. }
  154. void Model::setCreatedDt(const QDateTime &dt)
  155. {
  156. if (dt != getCreatedDt()) {
  157. createdDateTime = dt.toString(dtFormat);
  158. createdDateTimeChanged();
  159. }
  160. }
  161. void Model::setLastModifiedDt(const QDateTime &dt)
  162. {
  163. if (dt != getLastModifiedDt()) {
  164. lastModifiedDateTime = dt.toString(dtFormat);
  165. lastModifiedDateTimeChanged();
  166. }
  167. }
  168. CWF_END_NAMESPACE