SQLite3ServerPlugin.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file
  11. /// \brief Contains code to call sqlite3_exec over a network that does not support shared file handles.
  12. #ifndef ___SQLITE_3_SERVER_PLUGIN_H
  13. #define ___SQLITE_3_SERVER_PLUGIN_H
  14. /// \brief Control if SQLite3 statements execute in a thread
  15. /// \details sqlite3_exec is blocking and will therefore block other operations in the same program<BR>
  16. /// If defined, sqlite3_exec executes in a thread so that doesn't happen<BR>
  17. /// If the only thing this system is doing is running SQLite, then you'll get marginally better performance by commenting it out.
  18. /// \ingroup SQL_LITE_3_PLUGIN
  19. #define SQLite3_STATEMENT_EXECUTE_THREADED
  20. #include "RakNetTypes.h"
  21. #include "Export.h"
  22. #include "PluginInterface2.h"
  23. #include "PacketPriority.h"
  24. #include "SocketIncludes.h"
  25. #include "DS_Multilist.h"
  26. #include "RakString.h"
  27. #include "sqlite3.h"
  28. #include "SQLite3PluginCommon.h"
  29. #ifdef SQLite3_STATEMENT_EXECUTE_THREADED
  30. #include "ThreadPool.h"
  31. #endif
  32. class RakPeerInterface;
  33. namespace RakNet
  34. {
  35. /// \brief Exec SQLLite commands over the network
  36. /// \details SQLite version 3 supports remote calls via networked file handles, but not over the regular internet<BR>
  37. /// This plugin will serialize calls to and results from sqlite3_exec<BR>
  38. /// That's all it does - any remote system can execute SQL queries.<BR>
  39. /// Intended as a starting platform to derive from for more advanced functionality (security over who can query, etc).<BR>
  40. /// Compatible as a plugin with both RakPeerInterface and PacketizedTCP
  41. /// \ingroup SQL_LITE_3_PLUGIN
  42. class RAK_DLL_EXPORT SQLite3ServerPlugin : public PluginInterface2
  43. {
  44. public:
  45. SQLite3ServerPlugin();
  46. virtual ~SQLite3ServerPlugin();
  47. /// Associate identifier with dbHandle, so when we get calls to operate on identifier, we use dbhandle
  48. /// If SQLite3_STATEMENT_EXECUTE_THREADED is defined, will start the execution thread the first time a dbHandle is added.
  49. /// \return true on success, false on dbIdentifier empty, or already in use
  50. virtual bool AddDBHandle(RakNet::RakString dbIdentifier, sqlite3 *dbHandle, bool dbAutoCreated=false);
  51. /// Stop using a dbHandle, lookup either by identifier or by pointer.
  52. /// If SQLite3_STATEMENT_EXECUTE_THREADED is defined, do not call this while processing commands, since the commands run in a thread and might be using the dbHandle
  53. /// Call before closing the handle or else SQLite3Plugin won't know that it was closed, and will continue using it
  54. void RemoveDBHandle(RakNet::RakString dbIdentifier, bool alsoCloseConnection=false);
  55. void RemoveDBHandle(sqlite3 *dbHandle, bool alsoCloseConnection=false);
  56. /// \internal For plugin handling
  57. virtual PluginReceiveResult OnReceive(Packet *packet);
  58. virtual void OnAttach(void);
  59. virtual void OnDetach(void);
  60. /// \internal
  61. struct NamedDBHandle
  62. {
  63. RakNet::RakString dbIdentifier;
  64. sqlite3 *dbHandle;
  65. bool dbAutoCreated;
  66. RakNet::TimeMS whenCreated;
  67. };
  68. #ifdef SQLite3_STATEMENT_EXECUTE_THREADED
  69. virtual void Update(void);
  70. /// \internal
  71. struct SQLExecThreadInput
  72. {
  73. SQLExecThreadInput() {data=0; packet=0;}
  74. char *data;
  75. unsigned int length;
  76. SystemAddress sender;
  77. RakNet::TimeMS whenMessageArrived;
  78. sqlite3 *dbHandle;
  79. RakNet::Packet *packet;
  80. };
  81. /// \internal
  82. struct SQLExecThreadOutput
  83. {
  84. SQLExecThreadOutput() {data=0; packet=0;}
  85. char *data;
  86. unsigned int length;
  87. SystemAddress sender;
  88. RakNet::Packet *packet;
  89. };
  90. #endif // SQLite3_STATEMENT_EXECUTE_THREADED
  91. protected:
  92. virtual void StopThreads(void);
  93. // List of databases added with AddDBHandle()
  94. DataStructures::Multilist<ML_ORDERED_LIST, NamedDBHandle, RakNet::RakString> dbHandles;
  95. #ifdef SQLite3_STATEMENT_EXECUTE_THREADED
  96. // The point of the sqlThreadPool is so that SQL queries, which are blocking, happen in the thread and don't slow down the rest of the application
  97. // The sqlThreadPool has a queue for incoming processing requests. As systems disconnect their pending requests are removed from the list.
  98. ThreadPool<SQLExecThreadInput, SQLExecThreadOutput> sqlThreadPool;
  99. #endif
  100. };
  101. };
  102. extern bool operator<( const DataStructures::MLKeyRef<RakNet::RakString> &inputKey, const RakNet::SQLite3ServerPlugin::NamedDBHandle &cls );
  103. extern bool operator>( const DataStructures::MLKeyRef<RakNet::RakString> &inputKey, const RakNet::SQLite3ServerPlugin::NamedDBHandle &cls );
  104. extern bool operator==( const DataStructures::MLKeyRef<RakNet::RakString> &inputKey, const RakNet::SQLite3ServerPlugin::NamedDBHandle &cls );
  105. #endif
粤ICP备19079148号