Logo Pico-Framework A web-first embedded framework for C++
Loading...
Searching...
No Matches
FrameworkModel Class Reference

Provides a basic JSON-backed record model. More...

#include <FrameworkModel.h>

+ Inheritance diagram for FrameworkModel:
+ Collaboration diagram for FrameworkModel:

Public Member Functions

 FrameworkModel (const std::string &path)
 Constructor.
 
bool load ()
 Loads the JSON collection from storage.
 
bool save ()
 Saves the current collection to storage.
 
std::vector< nlohmann::json > all () const
 Returns all items in the collection.
 
std::optional< nlohmann::json > find (const std::string &id) const
 Finds an item by ID.
 
bool create (const nlohmann::json &item)
 Adds a new item to the collection.
 
bool update (const std::string &id, const nlohmann::json &updatedItem)
 Updates an item by ID.
 
bool remove (const std::string &id)
 Removes an item by ID.
 
nlohmann::json toJson () const
 Returns the full collection as a JSON array object.
 
nlohmann::json findAsJson (const std::string &id) const
 Finds a single item by ID and returns it as JSON or null.
 
bool save (const std::string &id, const json &data)
 Saves a single item by ID and JSON object.
 
bool createFromJson (const nlohmann::json &obj)
 
bool updateFromJson (const std::string &id, const nlohmann::json &updates)
 
nlohmann::json deleteAsJson (const std::string &id)
 
bool saveAll ()
 
template<typename T >
getValue (const std::string &key, const T &defaultValue=T())
 Reads a single top-level key from the model file.
 
template<typename T >
void setValue (const std::string &key, const T &value)
 Sets a single top-level key in the model file.
 

Protected Member Functions

virtual std::string getIdField () const
 Returns the JSON key used as the record ID.
 

Protected Attributes

nlohmann::json collection = nlohmann::json::array()
 In-memory array of records.
 

Private Attributes

JsonServicejsonService = nullptr
 Underlying JSON persistence layer

 
std::string storagePath
 File path for this model.
 

Detailed Description

FrameworkModel abstracts away JSON loading/saving and record manipulation. Subclass it to represent specific collections, optionally overriding getIdField() if the record ID is not "id".

Definition at line 36 of file FrameworkModel.h.

Constructor & Destructor Documentation

◆ FrameworkModel()

FrameworkModel::FrameworkModel ( const std::string &  path)

Constructor.

Parameters
storagePointer to a StorageManager (e.g. SD, flash).
pathPath to the backing JSON file.
Parameters
storagePointer to a StorageManager (e.g. SD, flash).
pathPath to the backing JSON file.

Definition at line 26 of file FrameworkModel.cpp.

27 : storagePath(path) {}
std::string storagePath
File path for this model.

Member Function Documentation

◆ all()

std::vector< nlohmann::json > FrameworkModel::all ( ) const

Returns all items in the collection.

Definition at line 67 of file FrameworkModel.cpp.

68{
69 if (collection.empty())
70 {
71 return {};
72 }
73 std::vector<nlohmann::json> items;
74 for (const auto &item : collection)
75 {
76 TRACE("[FrameworkModel::all] Item: %s\n", item.dump(4).c_str());
77 items.push_back(item);
78 }
79 return items;
80}
#define TRACE(...)
Default trace (INFO level).
Definition DebugTrace.h:187
nlohmann::json collection
In-memory array of records.

References collection, and TRACE.

◆ create()

bool FrameworkModel::create ( const nlohmann::json &  item)

Adds a new item to the collection.

Parameters
itemJSON object to insert.
Returns
true if added successfully; false if missing ID or already exists.
Parameters
itemJSON object to insert.
Returns
true if added successfully; false if missing ID or already exists.

Definition at line 97 of file FrameworkModel.cpp.

98{
99 std::string idField = getIdField();
100 if (!item.contains(idField))
101 return false;
102 std::string id = item[idField];
103 if (find(id))
104 return false;
105 collection.push_back(item);
106 return true;
107}
virtual std::string getIdField() const
Returns the JSON key used as the record ID.
std::optional< nlohmann::json > find(const std::string &id) const
Finds an item by ID.

References collection, find(), and getIdField().

+ Here is the call graph for this function:

◆ createFromJson()

bool FrameworkModel::createFromJson ( const nlohmann::json &  obj)

Definition at line 166 of file FrameworkModel.cpp.

167{
168 std::string idField = getIdField();
169 if (!obj.contains(idField))
170 return false;
171 return save(obj[idField], obj);
172}
bool save()
Saves the current collection to storage.

References getIdField(), and save().

+ Here is the call graph for this function:

◆ deleteAsJson()

nlohmann::json FrameworkModel::deleteAsJson ( const std::string &  id)

Definition at line 193 of file FrameworkModel.cpp.

194{
195 std::string idField = getIdField();
196 for (auto it = collection.begin(); it != collection.end(); ++it)
197 {
198 if (it->contains(idField) && (*it)[idField] == id)
199 {
200 nlohmann::json removed = *it;
201 collection.erase(it);
202 return saveAll() ? removed : nullptr;
203 }
204 }
205 return nullptr;
206}

References collection, getIdField(), and saveAll().

+ Here is the call graph for this function:

◆ find()

std::optional< nlohmann::json > FrameworkModel::find ( const std::string &  id) const

Finds an item by ID.

Parameters
idThe value of the ID field to match.
Returns
The matching JSON object, or nullopt if not found.
Parameters
idThe value of the ID field to match.
Returns
The matching JSON object, or nullopt if not found.

Definition at line 83 of file FrameworkModel.cpp.

84{
85 std::string idField = getIdField();
86 for (const auto &item : collection)
87 {
88 if (item.contains(idField) && item[idField] == id)
89 {
90 return item;
91 }
92 }
93 return std::nullopt;
94}

References collection, and getIdField().

Referenced by create(), and findAsJson().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ findAsJson()

nlohmann::json FrameworkModel::findAsJson ( const std::string &  id) const

Finds a single item by ID and returns it as JSON or null.

Definition at line 140 of file FrameworkModel.cpp.

141{
142 auto result = find(id);
143 return result ? *result : nlohmann::json(nullptr);
144}

References find().

+ Here is the call graph for this function:

◆ getIdField()

virtual std::string FrameworkModel::getIdField ( ) const
inlineprotectedvirtual

Defaults to "id", but can be overridden by subclasses.

Definition at line 172 of file FrameworkModel.h.

172{ return "id"; }

Referenced by create(), createFromJson(), deleteAsJson(), find(), remove(), save(), update(), and updateFromJson().

+ Here is the caller graph for this function:

◆ getValue()

template<typename T >
T FrameworkModel::getValue ( const std::string &  key,
const T &  defaultValue = T() 
)
inline

This is separate from array-style records and useful for persistent app state.

Template Parameters
TExpected return type
Parameters
keyJSON key name
defaultValueReturned if key is not present
Returns
Value from JSON or default

Definition at line 129 of file FrameworkModel.h.

130 {
132 if(!jsonService)
133 {
134 printf("[FrameworkModel] JsonService not available\n");
135 return defaultValue;
136 }
137 const auto &data = jsonService->data();
138 if (data.contains(key))
139 {
140 return data[key].get<T>();
141 }
142 return defaultValue;
143 }
static constexpr std::uintptr_t getTypeKey()
Definition AppContext.h:91
JsonService * jsonService
Underlying JSON persistence layer
nlohmann::json & data()
Access the internal JSON object.

References JsonService::data(), AppContext::getTypeKey(), and jsonService.

Referenced by PicoModel::onNetworkReady(), and PicoModel::restoreState().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ load()

bool FrameworkModel::load ( )

Loads the JSON collection from storage.

Returns
true if successful.
Returns
true if successful.

Definition at line 30 of file FrameworkModel.cpp.

31{
33 if(!jsonService)
34 {
35 printf("Failed to get JsonService\n");
36 return false;
37 }
38 if(storagePath.empty())
39 {
40 printf("[FrameworkModel] No storage path set, cannot load data\n");
41 return false;
42 }
43 TRACE("[FrameworkModel] Loading data from %s\n", storagePath.c_str());
45 return false;
46 collection = jsonService->data().value("items", nlohmann::json::array());
47 if (collection.empty())
48 {
49 TRACE("No items found in %s\n", storagePath.c_str());
50 return false;
51 }
52 else{
53 TRACE("collection: %s\n", collection.dump(4).c_str());
54 }
55 return true;
56}
bool load(const std::string &path)
Load a JSON file from storage.

References collection, JsonService::data(), AppContext::getTypeKey(), jsonService, JsonService::load(), storagePath, and TRACE.

Referenced by PicoModel::restoreState().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove()

bool FrameworkModel::remove ( const std::string &  id)

Removes an item by ID.

Parameters
idThe ID of the item to remove.
Returns
true if removed; false if not found.
Parameters
idThe ID of the item to remove.
Returns
true if removed; false if not found.

Definition at line 125 of file FrameworkModel.cpp.

126{
127 std::string idField = getIdField();
128 for (auto it = collection.begin(); it != collection.end(); ++it)
129 {
130 if (it->contains(idField) && (*it)[idField] == id)
131 {
132 collection.erase(it);
133 return true;
134 }
135 }
136 return false;
137}

References collection, and getIdField().

+ Here is the call graph for this function:

◆ save() [1/2]

bool FrameworkModel::save ( )

Saves the current collection to storage.

Returns
true if successful.
Returns
true if successful.

Definition at line 59 of file FrameworkModel.cpp.

60{
62 jsonService->data()["items"] = collection;
64}
bool save(const std::string &path) const
Save the current JSON data to storage.

References collection, JsonService::data(), AppContext::getTypeKey(), jsonService, JsonService::save(), and storagePath.

Referenced by createFromJson(), save(), PicoModel::saveState(), and updateFromJson().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ save() [2/2]

bool FrameworkModel::save ( const std::string &  id,
const json data 
)

Saves the current collection to storage. (single record)

Returns
true if successful.

(single record)

Definition at line 147 of file FrameworkModel.cpp.

148{
149 std::string idField = getIdField();
150
151 for (auto &item : collection)
152 {
153 if (item.contains(idField) && item[idField] == id)
154 {
155 item = data;
156 return save();
157 }
158 }
159
160 // If not found, append
161 collection.push_back(data);
162 return save();
163}

References collection, getIdField(), and save().

+ Here is the call graph for this function:

◆ saveAll()

bool FrameworkModel::saveAll ( )

Definition at line 209 of file FrameworkModel.cpp.

210{
212 jsonService->data()["items"] = collection;
214}

References collection, JsonService::data(), AppContext::getTypeKey(), jsonService, JsonService::save(), and storagePath.

Referenced by deleteAsJson().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setValue()

template<typename T >
void FrameworkModel::setValue ( const std::string &  key,
const T &  value 
)
inline

This does not affect the array-style record collection.

Template Parameters
TType of value to store
Parameters
keyJSON key
valueValue to assign

Definition at line 154 of file FrameworkModel.h.

155 {
157 if(!jsonService)
158 {
159 printf("[FrameworkModel] JsonService not available\n");
160 return;
161 }
162 jsonService->data()[key] = value;
163 }

References JsonService::data(), AppContext::getTypeKey(), and jsonService.

Referenced by PicoModel::saveState(), and PicoModel::setLedState().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ toJson()

nlohmann::json FrameworkModel::toJson ( ) const
inline

Definition at line 100 of file FrameworkModel.h.

101 {
102 return nlohmann::json(collection);
103 }

References collection.

◆ update()

bool FrameworkModel::update ( const std::string &  id,
const nlohmann::json &  updatedItem 
)

Updates an item by ID.

Parameters
idThe ID of the item to update.
updatedItemThe new item JSON to replace the old one.
Returns
true if update succeeded; false if not found.
Parameters
idThe ID of the item to update.
updatedItemThe new item JSON to replace the old one.
Returns
true if update succeeded; false if not found.

Definition at line 110 of file FrameworkModel.cpp.

111{
112 std::string idField = getIdField();
113 for (auto &item : collection)
114 {
115 if (item.contains(idField) && item[idField] == id)
116 {
117 item = updatedItem;
118 return true;
119 }
120 }
121 return false;
122}

References collection, and getIdField().

+ Here is the call graph for this function:

◆ updateFromJson()

bool FrameworkModel::updateFromJson ( const std::string &  id,
const nlohmann::json &  updates 
)

Definition at line 175 of file FrameworkModel.cpp.

176{
177 std::string idField = getIdField();
178 for (auto &item : collection)
179 {
180 if (item.contains(idField) && item[idField] == id)
181 {
182 for (auto &el : updates.items())
183 {
184 item[el.key()] = el.value(); // Patch keys
185 }
186 return save(id, item);
187 }
188 }
189 return false;
190}

References collection, getIdField(), and save().

+ Here is the call graph for this function:

Member Data Documentation

◆ collection

nlohmann::json FrameworkModel::collection = nlohmann::json::array()
protected

◆ jsonService

JsonService* FrameworkModel::jsonService = nullptr
private

Definition at line 177 of file FrameworkModel.h.

Referenced by getValue(), load(), save(), saveAll(), and setValue().

◆ storagePath

std::string FrameworkModel::storagePath
private

Definition at line 178 of file FrameworkModel.h.

Referenced by load(), save(), and saveAll().


The documentation for this class was generated from the following files: