~vbursian/research-assistant/intervers

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