pianod2
multisource multiuser scriptable networked music player
datastore.h
Go to the documentation of this file.
1 
9 #pragma once
10 
11 #include <config.h>
12 
13 #include <ctime>
14 
15 #include <string>
16 #include <stdexcept>
17 #include <unordered_map>
18 #include <functional>
19 
20 #include <parsnip/parsnip.h>
21 
22 #include "ratings.h"
23 
25 namespace UserData {
26  namespace Key {
27  // Keys for type/origin and name/identity
28  extern const char *DataOrigin;
29  extern const char *DataIdentity;
30  extern const char *TheData;
31 
32  // Access keys
33  extern const char *PlaylistRatings;
34  extern const char *TrackRatings;
35  extern const char *OverplayedTracks;
36  } // namespace Key
37 
38  // For handling ratings/string conversions.
39  template <typename T>
40  inline T type_convert (const T value, const T) {
41  return value;
42  };
43  inline std::string type_convert (const Rating value, const std::string &) {
44  return RATINGS[value];
45  }
46  inline Rating type_convert (const std::string &value, Rating) {
47  return RATINGS[value];
48  };
49 
56  class DataStore {
57  public:
58  virtual ~DataStore (void){};
60  virtual const std::string &origin (void) const = 0;
62  virtual const std::string &identity (void) const = 0;
66  virtual bool reconstitute (const Parsnip::Data &data) = 0;
69  virtual Parsnip::Data persist() const = 0;
70  bool isSourceData (void) const;
71  static bool isSourceData (const std::string &origin);
72  };
73 
76  class JSONData : public DataStore, public Parsnip::Data {
77  const std::string originid;
78  const std::string id;
79 
80  public:
81  JSONData (const std::string &, const std::string &);
82  JSONData (const Parsnip::Data &);
83  virtual const std::string &origin (void) const override;
84  virtual const std::string &identity (void) const override;
85  virtual bool reconstitute (const Parsnip::Data &data) override;
86  virtual Parsnip::Data persist() const override;
87  void rename (const std::string new_id);
88  };
89 
94  template <class TKey = std::string, class TValue = std::string, class TStorage = TValue>
95  class Dictionary : public DataStore, public std::unordered_map<TKey, TValue> {
96  const std::string originid;
97  const std::string id;
98 
99  public:
100  Dictionary (const std::string &_origin, const std::string &_id) : originid (_origin), id (_id) {
101  }
102  virtual const std::string &origin (void) const override {
103  return originid;
104  };
105  virtual const std::string &identity (void) const override {
106  return id;
107  };
108  void rename (const std::string new_id) {
109  const_cast<std::string &> (id) = new_id;
110  }
111  bool add (const TKey &key, const TValue &value) {
112  try {
113  std::pair<TKey, TValue> p (key, value);
114  std::pair<typename std::unordered_map<TKey, TValue>::iterator, bool> result = this->insert (p);
115  return result.second;
116  } catch (...) {
117  return false;
118  }
119  }
120  const TValue &get (const TKey &key, const TValue &def) const {
121  auto it = this->find (key);
122  return (it == this->end() ? def : it->second);
123  }
124 
125  Dictionary (const Parsnip::Data &data)
126  : originid (data[Key::DataOrigin].asString()), id (data[Key::DataIdentity].asString()) {
127  reconstitute (data[Key::TheData]);
128  }
129 
130  virtual bool reconstitute (const Parsnip::Data &data) override {
131  std::function<void (const std::string &, const TStorage &)> handler
132  = [this] (const std::string &key, const TStorage &value) {
133  (*this)[key] = type_convert (value, TValue{});
134  };
135  data.foreach (handler);
136  return true;
137  }
138 
139  virtual Parsnip::Data persist() const override {
141  for (auto const &item : *this) {
142  data[item.first] = type_convert (item.second, TStorage{});
143  }
146  this->origin(),
148  this->identity(),
149  Key::TheData,
150  std::move (data)};
151  };
152  };
153 
158  class Ratings : public Dictionary<std::string, Rating, std::string> {
159  public:
161  static Ratings *retrieve (const User *user, const std::string &ratingKind, const std::string &key);
162  static Ratings *retrieve (User *user, const std::string &ratingKind, const std::string &key);
163  };
164 
169  class OverplayedList : public Dictionary<std::string, time_t> {
170  public:
171  OverplayedList (const std::string &ratingGroup)
172  : Dictionary<std::string, time_t> (Key::OverplayedTracks, ratingGroup){};
173  OverplayedList (const Parsnip::Data &json) : Dictionary (json) {
174  }
175  bool isExpired (const std::string &song_id);
176  static OverplayedList *retrieve (const User *user, const std::string &key);
177  static OverplayedList *retrieve (User *user, const std::string &key);
178  };
179 
180 } // namespace UserData
Generic data type.
Definition: parsnip.h:81
void foreach(std::function< void(const std::string &, DataType)> func) const
Iterate over all dictionary members, calling a function with each key and value.
Definition: parsnip.h:410
static const struct Parsnip::Data::dictionary_t Dictionary
Dictionary flag type/value.
union Parsnip::Data::data_t data
Storage mechanism for user data.
Definition: datastore.h:56
virtual const std::string & identity(void) const =0
Retrieve the identity (primary identifier) of the data in this storage unit.
virtual bool reconstitute(const Parsnip::Data &data)=0
Restore data from a JSON source.
virtual ~DataStore(void)
Definition: datastore.h:58
bool isSourceData(void) const
Definition: datastore.cpp:37
virtual const std::string & origin(void) const =0
Retrieve the origin (type of data) stored in this storage unit.
virtual Parsnip::Data persist() const =0
Persist data using Parsnip.
Store key-value pairs of arbitrary key and value types.
Definition: datastore.h:95
void rename(const std::string new_id)
Definition: datastore.h:108
Dictionary(const Parsnip::Data &data)
Definition: datastore.h:125
bool add(const TKey &key, const TValue &value)
Definition: datastore.h:111
virtual bool reconstitute(const Parsnip::Data &data) override
Restore data from a JSON source.
Definition: datastore.h:130
Dictionary(const std::string &_origin, const std::string &_id)
Definition: datastore.h:100
const std::string originid
Definition: datastore.h:96
virtual const std::string & origin(void) const override
Retrieve the origin (type of data) stored in this storage unit.
Definition: datastore.h:102
const std::string id
Definition: datastore.h:97
virtual Parsnip::Data persist() const override
Persist data using Parsnip.
Definition: datastore.h:139
virtual const std::string & identity(void) const override
Retrieve the identity (primary identifier) of the data in this storage unit.
Definition: datastore.h:105
const TValue & get(const TKey &key, const TValue &def) const
Definition: datastore.h:120
Store key-value pairs of string keys & mixed types using Parsnip::Data.
Definition: datastore.h:76
virtual const std::string & origin(void) const override
Retrieve the origin (type of data) stored in this storage unit.
Definition: datastore.cpp:54
virtual Parsnip::Data persist() const override
Persist data using Parsnip.
Definition: datastore.cpp:71
virtual const std::string & identity(void) const override
Retrieve the identity (primary identifier) of the data in this storage unit.
Definition: datastore.cpp:58
JSONData(const std::string &, const std::string &)
Definition: datastore.cpp:45
const std::string originid
Definition: datastore.h:77
void rename(const std::string new_id)
Definition: datastore.cpp:62
virtual bool reconstitute(const Parsnip::Data &data) override
Restore data from a JSON source.
Definition: datastore.cpp:66
const std::string id
Definition: datastore.h:78
Container for lists of user overplayed songs.
Definition: datastore.h:169
bool isExpired(const std::string &song_id)
Definition: datastore.cpp:109
static OverplayedList * retrieve(const User *user, const std::string &key)
Retrieve overplayed list for a user.
Definition: datastore.cpp:142
OverplayedList(const std::string &ratingGroup)
Definition: datastore.h:171
OverplayedList(const Parsnip::Data &json)
Definition: datastore.h:173
Container for user ratings values (playlists & songs).
Definition: datastore.h:158
static Ratings * retrieve(const User *user, const std::string &ratingKind, const std::string &key)
Definition: datastore.cpp:101
Data about each user.
Definition: user.h:53
uint32_t value
Definition: audiooutput.cpp:68
Definition: musiccache.cpp:18
const char * DataOrigin
Definition: datastore.cpp:21
const char * TrackRatings
Definition: datastore.cpp:26
const char * DataIdentity
Definition: datastore.cpp:22
const char * OverplayedTracks
Definition: datastore.cpp:27
const char * TheData
Definition: datastore.cpp:23
const char * PlaylistRatings
Definition: datastore.cpp:25
User data storage.
Definition: sources.h:20
T type_convert(const T value, const T)
Definition: datastore.h:40
Parsnip serialization.
const RatingLookup RATINGS(ratings_def)
Ratings support.
Rating
Discrete ratings values.
Definition: ratings.h:24