//////////////////////////////////////////////////////////////////////////////// /*! @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 #include #include #include 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 & ,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 Databases; sDB_Info RootDB_Info; sDB_UUID RootDB_UUID; sVersion RootDB_Version; private://fields sNodePtr TheRoot; QMutex LoadedNodesMutex; std::map 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 & ); static bool HasToBeRefreshed (const std::pair & ); private://fields psDB_SQL_Net Net; sDB_SQL_Net::psNodeUUID LastSaved; sDB_SQL_Net::psNodeUUID LastRefreshed; }; //------------------------------------------------------------------------------ }//namespace DB_SQL_Net //------------------------------------------------------------------------------ } //namespace RA #endif