| 127 | } |
| 128 | |
| 129 | VersionedJson VersioningDatabase::updateVersionedJson(VersionedJson const& versionedJson) const { |
| 130 | RecursiveMutexLocker locker(m_mutex); |
| 131 | |
| 132 | auto& root = Root::singleton(); |
| 133 | CelestialMasterDatabase celestialDatabase; |
| 134 | |
| 135 | VersionedJson result = versionedJson; |
| 136 | Maybe<VersionNumber> targetVersion = m_currentVersions.maybe(versionedJson.identifier); |
| 137 | if (!targetVersion) |
| 138 | throw VersioningDatabaseException::format("Versioned JSON has an unregistered identifier '{}'", versionedJson.identifier); |
| 139 | |
| 140 | LuaCallbacks celestialCallbacks; |
| 141 | celestialCallbacks.registerCallback("parameters", [&celestialDatabase](Json const& coord) { |
| 142 | return celestialDatabase.parameters(CelestialCoordinate(coord))->diskStore(); |
| 143 | }); |
| 144 | |
| 145 | try { |
| 146 | for (auto const& updateScript : m_versionUpdateScripts.value(versionedJson.identifier.toLower())) { |
| 147 | if (result.version >= *targetVersion) |
| 148 | break; |
| 149 | |
| 150 | if (updateScript.fromVersion == result.version) { |
| 151 | auto scriptContext = m_luaRoot.createContext(); |
| 152 | scriptContext.load(*root.assets()->bytes(updateScript.script), updateScript.script); |
| 153 | scriptContext.setCallbacks("root", LuaBindings::makeRootCallbacks()); |
| 154 | scriptContext.setCallbacks("sb", LuaBindings::makeUtilityCallbacks()); |
| 155 | scriptContext.setCallbacks("celestial", celestialCallbacks); |
| 156 | scriptContext.setCallbacks("versioning", makeVersioningCallbacks()); |
| 157 | |
| 158 | result.content = scriptContext.invokePath<Json>("update", result.content); |
| 159 | if (!result.content) { |
| 160 | throw VersioningDatabaseException::format( |
| 161 | "Could not bring versionedJson with identifier '{}' and version {} forward to current version of {}, conversion script from {} to {} returned null (un-upgradeable)", |
| 162 | versionedJson.identifier, result.version, targetVersion, updateScript.fromVersion, updateScript.toVersion); |
| 163 | } |
| 164 | Logger::debug("Brought versionedJson '{}' from version {} to {}", |
| 165 | versionedJson.identifier, result.version, updateScript.toVersion); |
| 166 | result.version = updateScript.toVersion; |
| 167 | } |
| 168 | } |
| 169 | } catch (std::exception const& e) { |
| 170 | throw VersioningDatabaseException(strf("Could not bring versionedJson with identifier '{}' and version {} forward to current version of {}", |
| 171 | versionedJson.identifier, result.version, targetVersion), e); |
| 172 | } |
| 173 | |
| 174 | if (result.version > *targetVersion) { |
| 175 | throw VersioningDatabaseException::format( |
| 176 | "VersionedJson with identifier '{}' and version {} is newer than current version of {}, cannot load", |
| 177 | versionedJson.identifier, result.version, targetVersion); |
| 178 | } |
| 179 | |
| 180 | if (result.version != *targetVersion) { |
| 181 | throw VersioningDatabaseException::format( |
| 182 | "Could not bring VersionedJson with identifier '{}' and version {} forward to current version of {}, best version was {}", |
| 183 | versionedJson.identifier, result.version, targetVersion, result.version); |
| 184 | } |
| 185 | |
| 186 | return result; |
no test coverage detected