Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/StarVersioningDatabase.hpp
blob: be4c523389bc1a5449a0e02fc82f29cae0a8e41e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#pragma once

#include "StarJson.hpp"
#include "StarDataStream.hpp"
#include "StarThread.hpp"
#include "StarVersion.hpp"
#include "StarLuaRoot.hpp"

namespace Star {

STAR_STRUCT(VersionedJson);
STAR_CLASS(VersioningDatabase);

STAR_EXCEPTION(VersionedJsonException, StarException);
STAR_EXCEPTION(VersioningDatabaseException, StarException);

struct VersionedJson {
  static char const* const Magic;
  static size_t const MagicStringSize;

  // Writes and reads a binary file containing a versioned json with a magic
  // header marking it as a starbound versioned json file.  Writes using a
  // safe write/flush/swap.
  static VersionedJson readFile(String const& filename);
  static void writeFile(VersionedJson const& versionedJson, String const& filename);

  // Writes and reads a json containing a versioned json
  // This allows embedding versioned metadata within a file
  static VersionedJson fromJson(Json const& source);
  Json toJson() const;

  bool empty() const;

  // If the identifier does not match the given identifier, throws a
  // VersionedJsonException.
  void expectIdentifier(String const& expectedIdentifier) const;

  String identifier;
  VersionNumber version;
  Json content;
};

DataStream& operator>>(DataStream& ds, VersionedJson& versionedJson);
DataStream& operator<<(DataStream& ds, VersionedJson const& versionedJson);

class VersioningDatabase {
public:
  VersioningDatabase();

  // Converts the given content Json to a VersionedJson by marking it with the
  // given identifier and the current version configured in the versioning
  // config file.
  VersionedJson makeCurrentVersionedJson(String const& identifier, Json const& content) const;

  // Returns true if the version in this VersionedJson matches the configured
  // current version and does not need updating.
  bool versionedJsonCurrent(VersionedJson const& versionedJson) const;

  // Brings the given versioned json up to the current configured latest
  // version using update scripts.  If successful, returns the up to date
  // VersionedJson, otherwise throws VersioningDatabaseException.
  VersionedJson updateVersionedJson(VersionedJson const& versionedJson) const;

  // Convenience method, checkts the versionedJson expected identifier and then
  // brings the given versionedJson up to date and returns the content.
  Json loadVersionedJson(VersionedJson const& versionedJson, String const& expectedIdentifier) const;

private:
  struct VersionUpdateScript {
    String script;
    VersionNumber fromVersion;
    VersionNumber toVersion;
  };

  LuaCallbacks makeVersioningCallbacks() const;

  mutable RecursiveMutex m_mutex;
  mutable LuaRoot m_luaRoot;

  StringMap<VersionNumber> m_currentVersions;
  StringMap<List<VersionUpdateScript>> m_versionUpdateScripts;
};

}