• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MerginMaps / input / 6046428848

01 Sep 2023 06:59AM UTC coverage: 62.11% (+0.05%) from 62.056%
6046428848

push

github

web-flow
Merge pull request #2775 from MerginMaps/cppcheck

Cppcheck

7560 of 12172 relevant lines covered (62.11%)

102.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.0
/core/merginprojectmetadata.cpp
1
/***************************************************************************
2
 *                                                                         *
3
 *   This program is free software; you can redistribute it and/or modify  *
4
 *   it under the terms of the GNU General Public License as published by  *
5
 *   the Free Software Foundation; either version 2 of the License, or     *
6
 *   (at your option) any later version.                                   *
7
 *                                                                         *
8
 ***************************************************************************/
9

10
#include "merginprojectmetadata.h"
11
#include "coreutils.h"
12

13
#include <QDebug>
14
#include <QJsonArray>
15
#include <QJsonDocument>
16
#include <QJsonObject>
17
#include <algorithm>
18
#include <QFile>
19

20
MerginFile MerginFile::fromJsonObject( const QJsonObject &merginFileInfo )
5,867✔
21
{
22
  MerginFile merginFile;
5,867✔
23
  merginFile.checksum = merginFileInfo.value( QStringLiteral( "checksum" ) ).toString();
5,867✔
24
  merginFile.path = merginFileInfo.value( QStringLiteral( "path" ) ).toString();
5,867✔
25
  merginFile.size = merginFileInfo.value( QStringLiteral( "size" ) ).toInt();
5,867✔
26
  merginFile.mtime =  QDateTime::fromString( merginFileInfo.value( QStringLiteral( "mtime" ) ).toString(), Qt::ISODateWithMs ).toUTC();
5,867✔
27
  merginFile.diffSize = 0;
5,867✔
28

29
  if ( merginFileInfo.contains( QStringLiteral( "history" ) ) )
5,867✔
30
  {
31
    // "history" is only present if we request project info with "since=vXYZ" argument in the query.
32
    // It is useful for diffable files (.gpkg) to figure out which diff files we need to request
33
    // instead of having to download the whole .gpkg file.
34
    //
35
    // Changes to a diffable file can be pushed either through a diff or by uploading the whole file.
36
    // The latter is something we don't like to see as we can't apply geodiff processing - the clients
37
    // only should use it as the last resort - e.g. when table structures got modified.
38
    // If the whole history between our current version and the newest version is available with diffs,
39
    // then we can use them - otherwise we will have to pull the full .gpkg from server.
40

41
    QJsonObject history = merginFileInfo.value( QStringLiteral( "history" ) ).toObject();
6,796✔
42
    QList<int> versions;
3,398✔
43
    for ( QString key : history.keys() )
3,505✔
44
      versions << key.mid( 1 ).toInt();
3,505✔
45
    std::sort( versions.begin(), versions.end() );
3,398✔
46

47
    if ( versions.count() > 0 )
3,398✔
48
    {
49
      merginFile.pullCanUseDiff = true;
93✔
50
      for ( int key : versions )
200✔
51
      {
52
        QJsonObject obj = history.value( QString( "v%1" ).arg( key ) ).toObject();
214✔
53
        if ( obj.contains( "diff" ) )
107✔
54
        {
55
          QJsonObject diffObj = obj["diff"].toObject();
107✔
56
          int fileSize = diffObj["size"].toInt();
107✔
57
          merginFile.pullDiffFiles << qMakePair( key, fileSize );
107✔
58
        }
107✔
59
        else
60
        {
61
          // bad luck - a full file upload was done - we can't apply diffs
62
          merginFile.pullDiffFiles.clear();
×
63
          merginFile.pullCanUseDiff = false;
×
64
          break;
×
65
        }
66
      }
107✔
67
    }
68
    else
69
    {
70
      // this is not a diffable file if the history is empty ("history": {})
71
    }
72
  }
3,398✔
73

74
  return merginFile;
5,867✔
75
}
×
76

77

78
MerginProjectMetadata MerginProjectMetadata::fromJson( const QByteArray &data )
1,282✔
79
{
80
  MerginProjectMetadata project;
1,282✔
81

82
  QJsonDocument doc = QJsonDocument::fromJson( data );
1,282✔
83
  if ( !doc.isObject() )
1,282✔
84
  {
85
    qDebug() << "MerginProjectMetadata::fromJson: invalid content!";
×
86
    return project;
×
87
  }
88

89
  QJsonObject docObj = doc.object();
1,282✔
90

91
  // read metadata about project files
92
  QJsonValue vFiles = docObj.value( QStringLiteral( "files" ) );
2,564✔
93
  Q_ASSERT( vFiles.isArray() );
1,282✔
94
  QJsonArray vFilesArray = vFiles.toArray();
1,282✔
95
  for ( auto it = vFilesArray.constBegin(); it != vFilesArray.constEnd(); ++it )
7,149✔
96
  {
97
    project.files << MerginFile::fromJsonObject( it->toObject() );
5,867✔
98
  }
99

100
  project.name = docObj.value( QStringLiteral( "name" ) ).toString();
1,282✔
101
  project.projectNamespace = docObj.value( QStringLiteral( "namespace" ) ).toString();
1,282✔
102

103
  QJsonValue access = docObj.value( QStringLiteral( "access" ) );
2,564✔
104
  if ( access.isObject() )
1,282✔
105
  {
106
    QJsonArray writersnames = access.toObject().value( "writersnames" ).toArray();
2,564✔
107
    for ( QJsonValueRef tag : writersnames )
2,564✔
108
    {
109
      project.writersnames.append( tag.toString() );
1,282✔
110
    }
111
  }
1,282✔
112

113
  QString versionStr = docObj.value( QStringLiteral( "version" ) ).toString();
2,564✔
114
  if ( versionStr.isEmpty() )
1,282✔
115
  {
116
    project.version = 0;
×
117
  }
118
  else if ( versionStr.startsWith( "v" ) ) // cut off 'v' part from v123
1,282✔
119
  {
120
    versionStr = versionStr.mid( 1 );
1,282✔
121
    project.version = versionStr.toInt();
1,282✔
122
  }
123

124
  return project;
1,282✔
125
}
1,282✔
126

127
MerginProjectMetadata MerginProjectMetadata::fromCachedJson( const QString &metadataFilePath )
786✔
128
{
129
  QFile file( metadataFilePath );
786✔
130
  if ( file.open( QIODevice::ReadOnly ) )
786✔
131
  {
132
    return fromJson( file.readAll() );
1,250✔
133
  }
134
  return MerginProjectMetadata();
161✔
135
}
786✔
136

137
MerginFile MerginProjectMetadata::fileInfo( const QString &filePath ) const
283✔
138
{
139
  for ( const MerginFile &merginFile : files )
1,140✔
140
  {
141
    if ( merginFile.path == filePath )
1,140✔
142
      return merginFile;
283✔
143
  }
144
  qDebug() << "requested fileInfo() for non-existant file! " << filePath;
×
145
  return MerginFile();
×
146
}
147

148
MerginConfig MerginConfig::fromJson( const QByteArray &data )
120✔
149
{
150
  QJsonDocument doc = QJsonDocument::fromJson( data );
120✔
151
  MerginConfig config;
120✔
152

153
  if ( doc.isObject() )
120✔
154
  {
155
    QJsonObject docObj = doc.object();
119✔
156
    config.selectiveSyncEnabled = docObj.value( QStringLiteral( "input-selective-sync" ) ).toBool( false );
119✔
157
    config.selectiveSyncDir = docObj.value( QStringLiteral( "input-selective-sync-dir" ) ).toString();
119✔
158
    config.isValid = true;
119✔
159
  }
119✔
160
  else
161
  {
162
    CoreUtils::log( QStringLiteral( "MerginConfig" ), QStringLiteral( "Invalid content of a config file!" ) );
2✔
163
  }
164

165
  return config;
240✔
166
}
120✔
167

168
MerginConfig MerginConfig::fromFile( const QString &filePath )
280✔
169
{
170
  MerginConfig config;
280✔
171
  QFile file( filePath );
280✔
172

173
  if ( file.open( QIODevice::ReadOnly ) )
280✔
174
  {
175
    QByteArray data = file.readAll();
81✔
176
    config = MerginConfig::fromJson( data );
81✔
177
  }
81✔
178

179
  return config;
560✔
180
}
280✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc