Database.h
Go to the documentation of this file.
1 
20 #pragma once
21 
22 #include "Store.h"
23 #include "DatabaseInfo.h"
24 #include <Data/CString.h>
25 #include <WVector.h>
26 
27 namespace ConfigDB
28 {
29 class Database
30 {
31 public:
36  Database(const DatabaseInfo& typeinfo, const String& path)
37  : typeinfo(typeinfo), path(path.c_str()), updateRefs(new WeakRef[typeinfo.storeCount])
38  {
39  }
40 
41  virtual ~Database();
42 
43  String getName() const
44  {
45  auto pathstr = path.c_str();
46  auto sep = strrchr(pathstr, '/');
47  return sep ? &sep[1] : pathstr;
48  }
49 
50  String getPath() const
51  {
52  return path.c_str();
53  }
54 
58  StoreRef openStore(unsigned index);
59 
61 
66  void checkStoreRef(const StoreRef& ref);
67 
73  void queueUpdate(Store& store, Object::UpdateCallback&& callback);
74 
80  void checkUpdateQueue(Store& store);
81 
85  bool save(Store& store) const;
86 
94 
98  virtual const Format& getFormat(const Store& store) const;
99 
109  virtual bool handleFormatError(FormatError err, const Object& object, const String& arg);
110 
116  std::unique_ptr<ExportStream> createExportStream(const Format& format, const String& path = nullptr);
117 
121  size_t exportToStream(const Format& format, Print& output)
122  {
123  return format.exportToStream(*this, output);
124  }
125 
129  bool exportToFile(const Format& format, const String& filename);
130 
135  {
136  return format.importFromStream(*this, source);
137  }
138 
142  Status importFromFile(const Format& format, const String& filename);
143 
147  std::unique_ptr<ImportStream> createImportStream(const Format& format)
148  {
149  return format.createImportStream(*this);
150  }
151 
153 
154 private:
158  using WeakRef = std::weak_ptr<Store>;
159 
163  struct StoreCache {
164  std::shared_ptr<Store> store;
165 
166  explicit operator bool() const
167  {
168  return bool(store);
169  }
170 
171  void reset()
172  {
173  store.reset();
174  }
175 
176  bool typeIs(const PropertyInfo& storeInfo) const
177  {
178  return store && store->propinfoPtr == &storeInfo;
179  }
180 
181  bool isIdle()
182  {
183  return store && store.use_count() == 1;
184  }
185 
186  void resetIf(const DatabaseInfo& info)
187  {
188  if(!*this) {
189  return;
190  }
191  for(unsigned i = 0; i < info.storeCount; ++i) {
192  if(typeIs(info.stores[i])) {
193  reset();
194  break;
195  }
196  }
197  }
198  };
199 
203  struct UpdateQueueItem {
204  Database* database;
205  uint8_t storeIndex;
206  Object::UpdateCallback callback;
207 
208  bool operator==(const UpdateQueueItem& item) const
209  {
210  return database == item.database && storeIndex == item.storeIndex;
211  }
212  };
213 
214  std::shared_ptr<Store> loadStore(const PropertyInfo& storeInfo);
215 
216  CString path;
217 
218  // Hold store open for a brief period to avoid thrashing
219  static StoreCache readCache;
220  static StoreCache writeCache;
221  std::unique_ptr<WeakRef[]> updateRefs;
222  static Vector<UpdateQueueItem> updateQueue;
223  static bool cacheCallbackQueued;
224 };
225 
230 template <class ClassType> class DatabaseTemplate : public Database
231 {
232 public:
234  {
235  }
236 };
237 
238 } // namespace ConfigDB
Class to manage a NUL-terminated C-style string When storing persistent strings in RAM the regular St...
Definition: CString.h:27
const char * c_str() const
Definition: CString.h:99
Used by code generator to create specific template for Database
Definition: Database.h:231
DatabaseTemplate(const String &path)
Definition: Database.h:233
Definition: Database.h:30
const DatabaseInfo & typeinfo
Definition: Database.h:152
StoreUpdateRef lockStore(StoreRef &store)
Lock a store for writing (called by Object)
size_t exportToStream(const Format &format, Print &output)
Serialize the database to a stream.
Definition: Database.h:121
void checkUpdateQueue(Store &store)
Called by Store on completion of update so any queued updates can be started.
virtual bool handleFormatError(FormatError err, const Object &object, const String &arg)
Called during import.
StoreRef openStore(unsigned index)
Open a store instance, load it and return a shared pointer.
Status importFromStream(const Format &format, Stream &source)
De-serialize the entire database from a stream.
Definition: Database.h:134
StoreUpdateRef openStoreForUpdate(unsigned index)
std::unique_ptr< ImportStream > createImportStream(const Format &format)
Create a write-only stream for de-serializing the database.
Definition: Database.h:147
String getPath() const
Definition: Database.h:50
std::unique_ptr< ExportStream > createExportStream(const Format &format, const String &path=nullptr)
Create a read-only stream for serializing the database.
Status importFromFile(const Format &format, const String &filename)
De-serialize the entire database from a file.
void queueUpdate(Store &store, Object::UpdateCallback &&callback)
Queue an asynchronous update.
bool exportToFile(const Format &format, const String &filename)
Serialize the database to a single file.
void checkStoreRef(const StoreRef &ref)
Called from StoreRef destructor so database can manage caches.
bool save(Store &store) const
Called from Store::commit.
Database(const DatabaseInfo &typeinfo, const String &path)
Database instance.
Definition: Database.h:36
String getName() const
Definition: Database.h:43
virtual const Format & getFormat(const Store &store) const
Get the storage format to use for a store.
size_t exportToStream(const Object &object, Print &output) const override
Print object.
std::unique_ptr< ImportStream > createImportStream(Database &db) const override
Create a stream for de-serialising (writing) into the database Used when updating a database from a r...
Status importFromStream(Object &object, Stream &source) const override
De-serialise content from stream into object (RAM)
An object can contain other objects, properties and arrays.
Definition: Libraries/ConfigDB/src/include/ConfigDB/Object.h:37
Definition: StoreRef.h:29
Definition: StoreRef.h:46
Manages access to an object store, typically one file.
Definition: ConfigDB/src/include/ConfigDB/Store.h:43
Provides formatted output to stream.
Definition: Print.h:37
Base Stream class.
Definition: Wiring/Stream.h:33
The String class.
Definition: WString.h:133
Definition: Array.h:26
FormatError
Definition: Status.h:48
Definition: Formatter.h:20
Definition: DatabaseInfo.h:26
const PropertyInfo stores[]
Definition: DatabaseInfo.h:29
uint32_t storeCount
Definition: DatabaseInfo.h:28
Property metadata.
Definition: PropertyInfo.h:112
Definition: Status.h:54