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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
////////////////////////////////////////////////////////////////////////////////
/*! @file DB_SQL_Net.h RANet back-end, based on storage in a relational DB
accessed via SQL.
- Part of RANet - Research Assistant Net Library.
- Uses Qt v.5 - http://qt.io/
- Copyright(C) 2013-2020, Viktor E. Bursian, St.Petersburg, Russia.
VBursian AT gmail DOT com
*///////////////////////////////////////////////////////////////////////////////
#ifndef DB_SQL_Net_H
#define DB_SQL_Net_H
#include "Net.h"
#include "NodePtr.h"
#include "Database.h"
#include <QString>
#include <QObject>
#include <QThread>
#include <map>
namespace RA {
//------------------------------------------------------------------------------
ANNOUNCE_CLASS(sDB_SQL_Net)
namespace DB_SQL_Net {
ANNOUNCE_CLASS(sSynchronizer)
}
//-------------------------------------------------------------- sDB_SQL_Net ---
/*!
*/
class RANet_EXPORT sDB_SQL_Net : public sNet
{
public://types
ANNOUNCE_CLASS(sNodeUUID)
//........................................... sDB_SQL_Net::sNodeUUID ...
class RANet_EXPORT sNodeUUID : public sNodeLocation
{
public://static
static sNodeUUID ForTheRoot (psNet,sDB_UUID,rcsVersion);
public:
virtual ~sNodeUUID ()
{}
sNodeUUID (rcsNodeUUID other)
:sNodeLocation(other.Net)
,TheDBId(other.TheDBId)
,TheNodeId(other.TheNodeId)
{}
rsNodeUUID operator = (rcsNodeUUID other)
{
Net = other.Net;
TheDBId = other.TheDBId;
TheNodeId = other.TheNodeId;
return *this;
}
public://database reading format
explicit sNodeUUID (rcsString formatted_db_id
,rcsString formatted_node_id
,psNet net );
public://database writing format
sString FormattedDBId () const; //!< for DB storage
sString FormattedNodeId () const; //!< for DB storage
public:
sDB_UUID DBId () const
{ return TheDBId; }
bool operator == (rcsNodeUUID) const;
bool operator < (rcsNodeUUID) const;
public://implementation of inherited
virtual bool operator == (pcsNodeLocation) const;
virtual psNodeLocation Replica () const;
virtual psNodeLocation LocationForAttr (rcsAttrName) const;
private:
explicit sNodeUUID (psNet net
,sDB_UUID db_id
,QUuid node_id)
:sNodeLocation(net)
,TheDBId(db_id)
,TheNodeId(node_id)
{}
private://fields
sDB_UUID TheDBId; //!< Universally unique
QUuid TheNodeId; //!< Unique at least inside its DB.
};
//......................................................................
public:
virtual ~sDB_SQL_Net ();
sDB_SQL_Net ();
virtual bool SaveAll ();
virtual bool Preset (sString textual_URL);
public://implementation of inherited
virtual bool CreateNew ();
virtual bool PreOpenSetUp ();
virtual bool Open (sString textual_URL);
virtual bool Open ();
virtual void Close ();
virtual bool IsOpen ();
virtual sString DesktopInfoText ();
virtual rsNodePtr Root ();
virtual void RegisterNode (pcsNodeLocation location
,psNode node );
virtual sNodePtr GetNode (pcsNodeLocation);
virtual void GetAttrList (std::list<sAttribute> &
,pcsNodeLocation);
public:
void AddDBLink (rsDB_Link link);
void EditLink (rsDB_Link link);
void RemovePartition (psDatabase partition);
virtual bool LoadDatabases (bool recursive =true);
protected:
virtual psNode LoadNode (pcsNodeLocation);
virtual psNode FindNode (pcsNodeLocation);
virtual bool StoreNewNode (psNode ,rsTime when);
virtual bool UpdateNode (psNode ,rsTime when);
virtual bool StoreNewAttribute (pcsNodeLocation host
,rcsAttrName name
,pcsNodeLocation value
,rsTime when );
virtual bool RemoveAttribute (pcsNodeLocation host
,rcsAttrName name);
virtual bool RemoveAttribute (pcsNodeLocation host
,pcsNodeLocation value);
virtual bool GetNodeStorageTime (pcsNodeLocation,rsTime);
public:
virtual bool LoadRoot ();
virtual bool LoadDatabases (psDatabase ,bool recursive =true);
public: //static SQL-specific
static void RunSQL (rcsDB_Info part_info
,rcsString sql_text );
static void SetParamValue (rcsDB_Link partition
,rcsString param_key
,rcsString param_value);
static bool CreateNewPartition (rcsDB_Info
,bool initiate =true);
static bool CreateTables (rcsDB_Info
,bool initiate
//add params and root
=true);
static void ReplicatePartition (rcsDB_Info source
,rcsDB_Info destination
,int * progress = NULL);
static void ReplicatePartNodes (rcsDB_Link source
,rcsDB_Link destination
,int * progress = NULL);
static void ReplicatePartAttrs (rcsDB_Link source
,rcsDB_Link destination
,int * progress = NULL);
protected://static constants
static csString DBIdFieldDecl;
static csString NodeIdFieldDecl;
public://fields
std::map<sDB_UUID
,psDatabase> Databases;
sDB_Info RootDB_Info;
sDB_UUID RootDB_UUID;
sVersion RootDB_Version;
private://fields
sNodePtr TheRoot;
QMutex LoadedNodesMutex;
std::map<sNodeUUID
,psNode> LoadedNodes;
QThread * SynchronizationThread;
friend class DB_SQL_Net::sSynchronizer;
};
namespace DB_SQL_Net {
//------------------------------------------------------------------------------
//------------------------------------------------ DB_SQL_Net::sSynchronizer ---
/*! The sSynchronizer class.
@note Внимание! Классы, производные от QObject, нельзя декларировать
в cpp-файлах (как здесь хотелось бы). Сделать их nested (и private) тоже нельзя.
-- "Ну, кто так строит?!"
*/
class RANet_EXPORT sSynchronizer : public QObject
{
Q_OBJECT
public:
static const int StartDelay;
static const int OnIdlePause;
public:
virtual ~sSynchronizer ();
sSynchronizer (psDB_SQL_Net);
public slots:
void StartSaving ();
void SaveSome ();
void RefreshSome ();
signals:
void SaveMore ();
void RefreshMore ();
private slots:
private:
static bool HasToBeSaved
(const
std::pair<sDB_SQL_Net::sNodeUUID,psNode> &
);
static bool HasToBeRefreshed
(const
std::pair<sDB_SQL_Net::sNodeUUID,psNode> &
);
private://fields
psDB_SQL_Net Net;
sDB_SQL_Net::psNodeUUID LastSaved;
sDB_SQL_Net::psNodeUUID LastRefreshed;
};
//------------------------------------------------------------------------------
}//namespace DB_SQL_Net
//------------------------------------------------------------------------------
} //namespace RA
#endif
|