diff --git a/.gitignore b/.gitignore index fb151df..d8b9535 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ -.vs/ - -bin/ +.vs/* +.idea/* */x64 */obj @@ -9,15 +8,11 @@ bin/ *.lib *.dll *.pdb +*.obj -*/Debug -*/Release - -*/*/obj/* - -tools/PacketGenerator/generated +[Bb]inaries/* +[Tt]ools/PacketGenerator/generated *Server *Client -*.sln -*.sln +*.sln \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 71e3017..1a47a01 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ -[submodule "lib/netcpp"] - path = lib/netcpp +[submodule "Libraries/netcpp"] + path = Libraries/netcpp url = https://github.com/index1207/netcpp -[submodule "lib/oneTBB"] - path = lib/oneTBB - url = https://github.com/oneapi-src/oneTBB +[submodule "Libraries/oneTBB"] + path = Libraries/oneTBB + url = https://github.com/oneapi-src/oneTBB \ No newline at end of file diff --git a/Connector/ConnectorPlusPlus/ConnectorPlusPlus.vcxproj b/Connector/ConnectorPlusPlus/ConnectorPlusPlus.vcxproj deleted file mode 100644 index 2987129..0000000 --- a/Connector/ConnectorPlusPlus/ConnectorPlusPlus.vcxproj +++ /dev/null @@ -1,176 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - - - - - - - - - 17.0 - Win32Proj - {D0BACE1E-22B6-4AF1-90BD-1982A4EB3209} - ConnectorPlusPlus - 10.0 - - - - StaticLibrary - true - v143 - Unicode - - - StaticLibrary - false - v143 - true - Unicode - - - StaticLibrary - true - v143 - Unicode - - - StaticLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)bin\$(Configuration)\ - $(SolutionDir)bin\$(Configuration)\obj\$(ProjectName)\ - Connector++ - - - $(SolutionDir)bin\$(Configuration)\ - $(SolutionDir)bin\$(Configuration)\obj\$(ProjectName)\ - Connector++ - - - $(SolutionDir)bin\$(Configuration)\ - $(SolutionDir)bin\$(Configuration)\obj\$(ProjectName)\ - Connector++ - - - $(SolutionDir)bin\$(Configuration)\ - $(SolutionDir)bin\$(Configuration)\obj\$(ProjectName)\ - Connector++ - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)SvEngine\include;$(SolutionDir)lib\netcpp\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) - stdcpp20 - - - Console - true - $(SolutionDir)bin\$(Configuration);$(SolutionDir)lib\bin\$(Configuration);%(AdditionalLibraryDirectories) - SvEngine.lib;netcpp.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)SvEngine\include;$(SolutionDir)lib\netcpp\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) - stdcpp20 - - - Console - true - true - true - $(SolutionDir)bin\$(Configuration);$(SolutionDir)lib\bin\$(Configuration);%(AdditionalLibraryDirectories) - SvEngine.lib;netcpp.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)SvEngine\include;$(SolutionDir)lib\netcpp\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) - stdcpp20 - - - Console - true - $(SolutionDir)bin\$(Configuration);$(SolutionDir)lib\bin\$(Configuration);%(AdditionalLibraryDirectories) - SvEngine.lib;netcpp.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)SvEngine\include;$(SolutionDir)lib\netcpp\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) - stdcpp20 - - - Console - true - true - true - $(SolutionDir)bin\$(Configuration);$(SolutionDir)lib\bin\$(Configuration);%(AdditionalLibraryDirectories) - SvEngine.lib;netcpp.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - - \ No newline at end of file diff --git a/Connector/ConnectorPlusPlus/ConnectorPlusPlus.vcxproj.filters b/Connector/ConnectorPlusPlus/ConnectorPlusPlus.vcxproj.filters deleted file mode 100644 index 84e9abf..0000000 --- a/Connector/ConnectorPlusPlus/ConnectorPlusPlus.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 소스 파일 - - - 소스 파일 - - - - - 헤더 파일 - - - 헤더 파일 - - - \ No newline at end of file diff --git a/Connector/ConnectorPlusPlus/ConnectorPlusPlus.vcxproj.user b/Connector/ConnectorPlusPlus/ConnectorPlusPlus.vcxproj.user deleted file mode 100644 index 966b4ff..0000000 --- a/Connector/ConnectorPlusPlus/ConnectorPlusPlus.vcxproj.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - true - - \ No newline at end of file diff --git a/Connector/ConnectorPlusPlus/include/Client.hpp b/Connector/ConnectorPlusPlus/include/Client.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/Connector/ConnectorPlusPlus/include/Session.hpp b/Connector/ConnectorPlusPlus/include/Session.hpp deleted file mode 100644 index 58aa5c0..0000000 --- a/Connector/ConnectorPlusPlus/include/Session.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include - -#include "net/Context.hpp" - -using namespace net; - -namespace sv { - class Packet; - - enum class Failure - { - None, - Connect - }; - - class Session : public std::enable_shared_from_this - { - friend class Server; - using ServerFactory = std::function()>; - public: - Session(); - virtual ~Session(); - public: - void Run(std::unique_ptr sock); - Socket GetSocket(); - public: - void Disconnect(); - void Send(std::span buffer); - public: - virtual void OnConnected() {}; - virtual void OnDisconnected() {}; - virtual void OnReceive(std::span buffer, int length) {}; - virtual void OnFail(Failure cause) {}; - protected: - std::unique_ptr m_sock; - private: - void OnRecvCompleted(Context *context, bool isSuccess); - private: - std::shared_ptr m_ref; // TEMP - std::vector m_buffer; - net::Context m_recvCtx; - std::atomic m_isDisconnected; - }; -} \ No newline at end of file diff --git a/Connector/ConnectorPlusPlus/src/Client.cpp b/Connector/ConnectorPlusPlus/src/Client.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/Connector/ConnectorPlusPlus/src/Session.cpp b/Connector/ConnectorPlusPlus/src/Session.cpp deleted file mode 100644 index 1a9ee21..0000000 --- a/Connector/ConnectorPlusPlus/src/Session.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "Session.hpp" - -#include "net/Context.hpp" -#include "net/Exception.hpp" - -using namespace sv; - -Session::Session() : m_buffer(1024, '\0') { -} - -void Session::Run(std::unique_ptr sock) { - m_sock = std::move(sock); - - m_recvCtx.completed = bind(&Session::OnRecvCompleted, this, std::placeholders::_1, std::placeholders::_2); - m_recvCtx.buffer = m_buffer; - - m_sock->receive(&m_recvCtx); - m_ref = shared_from_this(); -} - -void Session::OnRecvCompleted(Context *context, bool isSuccess) { - if(!isSuccess || context->length == 0) { - Disconnect(); - return; - } - OnReceive(context->buffer.subspan(0, context->length), context->length); - m_sock->receive(context); -} - -Session::~Session() { -} - -void Session::Disconnect() { - if (!m_isDisconnected) - { - m_isDisconnected = true; - OnDisconnected(); - m_ref = nullptr; - } -} - -void Session::Send(std::span buffer) { - std::lock_guard lock(m_mtx); - if (!m_sock->send(buffer)) { - throw net::network_error("send()"); - } -} - -Socket Session::GetSocket() { - return *m_sock; -} \ No newline at end of file diff --git a/Connector/ConnectorSharp/Connector.cs b/Connector/ConnectorSharp/Connector.cs deleted file mode 100644 index 5a123d4..0000000 --- a/Connector/ConnectorSharp/Connector.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Threading; - -namespace Sv -{ - public enum FailCause - { - Connect - } - public class Connector - { - private Socket m_socket; - public Action OnConnect { get; set; } = (_) => { }; - public Action OnDisconnect { get; set; } = () => { }; - public Action OnReceive { get; set; } = (_) => { }; - public Action OnFail { get; set; } = (_) => { }; - - int _isDisconnected; - private SocketAsyncEventArgs _recvEvent; - - object _lock = new object(); - - public Connector() - { - m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - _recvEvent = new SocketAsyncEventArgs(); - _recvEvent.Completed += (object sender, SocketAsyncEventArgs args) => - { - if(args.SocketError == SocketError.Success) - { - Message msg = new Message(); - msg.RawData = args.Buffer; - msg.Length = args.BytesTransferred; - OnReceive(msg); - - m_socket.ReceiveAsync(args); - } - else - { - OnDisconnect(); - } - }; - _recvEvent.SetBuffer(new byte[1024], 0, 1024); - - OnConnect += (_) => m_socket.ReceiveAsync(_recvEvent); - - _isDisconnected = 0; - } - - public void Connect(IPEndPoint endpoint) - { - SocketAsyncEventArgs args = new SocketAsyncEventArgs(); - args.RemoteEndPoint = endpoint; - args.Completed += (object sender, SocketAsyncEventArgs connectArgs) => - { - if(connectArgs.SocketError == SocketError.Success) - { - OnConnect(connectArgs.RemoteEndPoint); - } - else - { - OnFail(FailCause.Connect); - } - }; - m_socket.ConnectAsync(args); - } - - public void Send(byte[] buffer) - { - lock (_lock) - { - m_socket.Send(buffer); - } - } - - public void Disconnect() - { - if (Interlocked.Exchange(ref _isDisconnected, 1) == 0) - { - m_socket.Disconnect(false); - } - } - } -} diff --git a/Connector/ConnectorSharp/ConnectorSharp.csproj b/Connector/ConnectorSharp/ConnectorSharp.csproj deleted file mode 100644 index ab5db8c..0000000 --- a/Connector/ConnectorSharp/ConnectorSharp.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Library - netcoreapp3.0 - false - $(SolutionDir)bin\ - - - diff --git a/Connector/ConnectorSharp/Message.cs b/Connector/ConnectorSharp/Message.cs deleted file mode 100644 index 55f8884..0000000 --- a/Connector/ConnectorSharp/Message.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Sv -{ - public class Message - { - public byte[] RawData { get; set; } - public int Length { get; set; } - } -} diff --git a/Connector/ConnectorSharp/Packet.cs b/Connector/ConnectorSharp/Packet.cs deleted file mode 100644 index 617c53f..0000000 --- a/Connector/ConnectorSharp/Packet.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; - -namespace Sv -{ - class Packet - { - private ushort m_id = 0; - private ushort m_size = 0; - - protected ushort m_writeOffset = 0; - protected ushort m_readOffset = 0; - protected byte[] m_buffer; - - public ushort Id => m_id; - public ushort Size => m_size; - - public Packet(ushort id) - { - m_buffer = new byte[1024]; - - BitConverter.TryWriteBytes(new Span(m_buffer, 0, sizeof(ushort)), id); - m_writeOffset += sizeof(ushort) + sizeof(ushort); // id + size - } - - public void Finish() - { - BitConverter.TryWriteBytes(new Span(m_buffer, 2, sizeof(ushort)), m_writeOffset); - } - - virtual protected void Write() { } - virtual protected void Read() - { - m_id = BitConverter.ToUInt16(m_buffer, m_readOffset); - m_readOffset += sizeof(ushort); - m_size = BitConverter.ToUInt16(m_buffer, m_readOffset); - m_readOffset += sizeof(ushort); - } - } -} diff --git a/Connector/ConnectorSharp/Test.gen.cs b/Connector/ConnectorSharp/Test.gen.cs deleted file mode 100644 index e69de29..0000000 diff --git a/SvEngine/PCH/pch.cpp b/Core/PCH/pch.cpp similarity index 100% rename from SvEngine/PCH/pch.cpp rename to Core/PCH/pch.cpp diff --git a/SvEngine/PCH/pch.h b/Core/PCH/pch.h similarity index 100% rename from SvEngine/PCH/pch.h rename to Core/PCH/pch.h diff --git a/Core/SvEngine.vcxproj b/Core/SvEngine.vcxproj new file mode 100644 index 0000000..8cb9b5f --- /dev/null +++ b/Core/SvEngine.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + AnyCPU + + + + 17.0 + Win32Proj + {0e19d820-b6be-4d23-805b-aad9ef0eea69} + SvEngine + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + v143 + + + + + + + + + + + + + + + $(SolutionDir)Binaries\$(Configuration)\ + $(SolutionDir)Binaries\$(Configuration)\obj\$(ProjectName)\ + svengine + + + $(SolutionDir)Binaries\$(Configuration)\ + $(SolutionDir)Binaries\$(Configuration)\obj\$(ProjectName)\ + svengine + + + + Level4 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_HAS_STD_BYTE=0;EXPORT_DLL + true + stdcpp20 + $(ProjectDir)include;$(ProjectDir)PCH;$(SolutionDir)Libraries\netcpp\include;$(SolutionDir)Libraries\oneTBB\include;$(SolutionDir)Libraries\mysql-connector\include\jdbc;%(AdditionalIncludeDirectories) + true + Use + pch.h + MultiThreadedDebugDLL + 4251 + + + Console + true + $(SolutionDir)Binaries\$(Configuration) + ws2_32.lib;netcpp.lib;mysqlcppconn.lib;%(AdditionalDependencies) + + + $(SolutionDir)Binaries\$(Configuration)\;%(AdditionalLibraryDirectories) + netcpp.lib;tbb12_debug.lib;odbc32.lib;%(AdditionalDependencies) + + + + + Level4 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_HAS_STD_BYTE=0;EXPORT_DLL + true + stdcpp20 + $(ProjectDir)include;$(ProjectDir)PCH;$(SolutionDir)Libraries\netcpp\include;$(SolutionDir)Libraries\oneTBB\include;$(SolutionDir)Libraries\mysql-connector\include\jdbc;%(AdditionalIncludeDirectories) + true + Use + pch.h + MultiThreadedDLL + None + 4251 + + + Console + true + true + false + $(SolutionDir)Binaries\$(Configuration) + ws2_32.lib;netcpp.lib;mysqlcppconn.lib;%(AdditionalDependencies) + + + $(SolutionDir)Binaries\$(Configuration)\;%(AdditionalLibraryDirectories) + netcpp.lib;tbb12.lib;odbc32.lib;%(AdditionalDependencies) + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SvEngine/SvEngine.vcxproj.filters b/Core/SvEngine.vcxproj.filters similarity index 80% rename from SvEngine/SvEngine.vcxproj.filters rename to Core/SvEngine.vcxproj.filters index 1fb8fe7..6ef43f6 100644 --- a/SvEngine/SvEngine.vcxproj.filters +++ b/Core/SvEngine.vcxproj.filters @@ -17,13 +17,7 @@ src\util - - - - - - @@ -31,6 +25,8 @@ + + @@ -68,18 +64,12 @@ include\core - + include\util - - - - - - @@ -89,5 +79,9 @@ + + + + \ No newline at end of file diff --git a/SvEngine/SvEngine.vcxproj.user b/Core/SvEngine.vcxproj.user similarity index 70% rename from SvEngine/SvEngine.vcxproj.user rename to Core/SvEngine.vcxproj.user index 76ff616..8d1b202 100644 --- a/SvEngine/SvEngine.vcxproj.user +++ b/Core/SvEngine.vcxproj.user @@ -7,16 +7,24 @@ $(SolutionDir)lib\bin\$(Configuration) WindowsLocalDebugger + + $(SolutionDir)lib\bin\$(Configuration) + WindowsLocalDebugger + $(SolutionDir)lib\bin\$(Configuration) WindowsLocalDebugger + $(SolutionDir)Binaries\$(Configuration) + WindowsLocalDebugger + + $(SolutionDir)lib\bin\$(Configuration) WindowsLocalDebugger - $(SolutionDir)lib\bin\$(Configuration) + $(SolutionDir)Binaries\$(Configuration) WindowsLocalDebugger \ No newline at end of file diff --git a/SvEngine/include/CoreHeader.hpp b/Core/include/CoreHeader.hpp similarity index 84% rename from SvEngine/include/CoreHeader.hpp rename to Core/include/CoreHeader.hpp index 76ac8ee..a5df3e6 100644 --- a/SvEngine/include/CoreHeader.hpp +++ b/Core/include/CoreHeader.hpp @@ -1,10 +1,11 @@ #pragma once +#include "Macro.hpp" +#include "Types.hpp" + #include #include -#include "Util/Types.hpp" - #include #include @@ -17,11 +18,12 @@ #include "Util/String.hpp" #include "Util/Random.hpp" #include "util/Math.hpp" -#include "Thread/TLSStorage.hpp" #include "Network/Packet.hpp" -#include "Subsystem/Engine.hpp" #include "Memory/Arena.hpp" #include "Memory/ObjectPool.hpp" +#include "Subsystem/Engine.hpp" +#include "Subsystem/Database.hpp" + using namespace net; \ No newline at end of file diff --git a/Core/include/Functor.hpp b/Core/include/Functor.hpp new file mode 100644 index 0000000..87b089f --- /dev/null +++ b/Core/include/Functor.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include "Subsystem/Engine.hpp" + +using CallbackType = std::function; + +class SVENGINE_API Functor +{ + USE_POOL(Functor) +public: + Functor() = default; + ~Functor() noexcept; + + Functor(CallbackType functor); + + template + Functor(void(T::*method)(Args...), T* ptr, Args... args) + { + functor = std::bind(method, ptr, args...); + } +public: + inline void operator()() const { functor(); } +private: + CallbackType functor; +}; + +class SVENGINE_API DelayedFunctor +{ +public: + DelayedFunctor() = default; + DelayedFunctor(uint64 execTime, std::shared_ptr functor); +public: + bool operator<(const DelayedFunctor& other) const; + bool operator>(const DelayedFunctor& other) const; +public: + uint64 execTime; + std::shared_ptr functor; +}; + +class SVENGINE_API FunctorProcessor +{ +public: + FunctorProcessor() = default; +public: + void Push(std::shared_ptr functor); + void Push(uint64 delay, std::shared_ptr functor); +public: + void Flush(); + void Fetch(); +private: + ConcurrencyQueue> m_functorQue; + ConcurrencyPriorityQueue> m_delayedFuncQue; +}; \ No newline at end of file diff --git a/SvEngine/include/GameFramework/Vector.hpp b/Core/include/GameFramework/Vector.hpp similarity index 97% rename from SvEngine/include/GameFramework/Vector.hpp rename to Core/include/GameFramework/Vector.hpp index 533825c..9e3c809 100644 --- a/SvEngine/include/GameFramework/Vector.hpp +++ b/Core/include/GameFramework/Vector.hpp @@ -16,7 +16,7 @@ class Vector2D Vector2D Normalize() { const auto len = Length(); - return Vector2D(x / len, y / len); + return Vector2D(static_cast(x / len), static_cast(y / len)); } void operator+=(Vector2D&& v) noexcept { @@ -91,8 +91,8 @@ class Vector2D static Vector2D Left() noexcept { return Vector2D(-1, 0); } static Vector2D Right() noexcept { return Vector2D(1, 0); } public: - T x; - T y; + mutable T x; + mutable T y; }; template diff --git a/Core/include/Macro.hpp b/Core/include/Macro.hpp new file mode 100644 index 0000000..7a74abb --- /dev/null +++ b/Core/include/Macro.hpp @@ -0,0 +1,23 @@ +#pragma once + +#ifdef EXPORT_DLL + #define SVENGINE_API __declspec(dllexport) +#else + #define SVENGINE_API __declspec(dllimport) +#endif + +#define CRASH() \ +{ \ + int* crash = nullptr; \ + __analysis_assume(crash != nullptr); \ + *crash = 0xDEAD; \ +} +#define ASSERT_CRASH(expr) \ +{ \ + if(!(expr)) \ + { \ + CRASH(); \ + __analysis_assume(expr); \ + } \ +} +#define MAKE_LOG_CATEGORY(name) namespace Category { static String name(L#name); } \ No newline at end of file diff --git a/SvEngine/include/Memory/Arena.hpp b/Core/include/Memory/Arena.hpp similarity index 98% rename from SvEngine/include/Memory/Arena.hpp rename to Core/include/Memory/Arena.hpp index 3d34cc5..2cbf2cb 100644 --- a/SvEngine/include/Memory/Arena.hpp +++ b/Core/include/Memory/Arena.hpp @@ -1,7 +1,7 @@ #pragma once template -class Arena +class SVENGINE_API Arena { static constexpr size_t alignment = alignof(std::max_align_t); public: diff --git a/SvEngine/include/Memory/ObjectPool.hpp b/Core/include/Memory/ObjectPool.hpp similarity index 100% rename from SvEngine/include/Memory/ObjectPool.hpp rename to Core/include/Memory/ObjectPool.hpp diff --git a/SvEngine/include/Network/Client.hpp b/Core/include/Network/Client.hpp similarity index 60% rename from SvEngine/include/Network/Client.hpp rename to Core/include/Network/Client.hpp index 6855322..1add439 100644 --- a/SvEngine/include/Network/Client.hpp +++ b/Core/include/Network/Client.hpp @@ -4,8 +4,8 @@ #include "Session.hpp" -class Client { - using ServerFactory = std::function()>; +class SVENGINE_API Client { + using ServerFactory = std::function; Client(); public: @@ -14,13 +14,13 @@ class Client { void Run(net::Endpoint endpoint); public: template - static inline std::shared_ptr Open() + static inline std::unique_ptr Open() { - auto client = std::shared_ptr(new Client); + auto client = std::unique_ptr(new Client); client->m_serverFactory = [] { - return MakeShared(); + return new T(); }; - return client; + return std::move(client); } private: void OnConnectCompleted(Context* context, bool isSuccess); diff --git a/SvEngine/include/Network/Packet.hpp b/Core/include/Network/Packet.hpp similarity index 92% rename from SvEngine/include/Network/Packet.hpp rename to Core/include/Network/Packet.hpp index 31609b2..2222313 100644 --- a/SvEngine/include/Network/Packet.hpp +++ b/Core/include/Network/Packet.hpp @@ -14,7 +14,7 @@ enum PacketType : uint8 RPC }; -class Packet { +class SVENGINE_API Packet { friend Session; using HandlerFunc = std::function)>; public: @@ -80,12 +80,14 @@ class Packet { public: void Parse(std::span buffer); + static uint16 GetPacketId(std::span buffer); + template - static std::shared_ptr ParseFrom(std::span buffer, uint16 id) + static std::shared_ptr ParseFrom(std::span buffer) { auto pk = MakeShared(); pk->Parse(buffer); - pk->SetId(id); + pk->SetId(GetPacketId(buffer)); return pk; } Vector& Data(); diff --git a/SvEngine/include/Network/Server.hpp b/Core/include/Network/Server.hpp similarity index 67% rename from SvEngine/include/Network/Server.hpp rename to Core/include/Network/Server.hpp index 90383b1..2656fbf 100644 --- a/SvEngine/include/Network/Server.hpp +++ b/Core/include/Network/Server.hpp @@ -6,9 +6,9 @@ #include -class Server { +class SVENGINE_API Server { friend class Session; - using ClientFactory = std::function()>; + using ClientFactory = std::function; Server(); public: ~Server(); @@ -17,13 +17,13 @@ class Server { void Cancel(); public: template - static inline std::shared_ptr Open() + static inline std::unique_ptr Open() { - auto server = std::shared_ptr(new Server); + auto server = std::unique_ptr(new Server); server->m_clientFactory = [] { - return MakeShared(); + return new T(); }; - return server; + return std::move(server); } private: void OnAcceptCompleted(net::Context* acceptContext, bool isSuccess); diff --git a/SvEngine/include/Network/Session.hpp b/Core/include/Network/Session.hpp similarity index 77% rename from SvEngine/include/Network/Session.hpp rename to Core/include/Network/Session.hpp index 9db0e25..8b9edd4 100644 --- a/SvEngine/include/Network/Session.hpp +++ b/Core/include/Network/Session.hpp @@ -16,11 +16,10 @@ enum class Failure Connect }; -class Session : public std::enable_shared_from_this +class SVENGINE_API Session { friend class Server; friend class Client; - using ServerFactory = std::function()>; USE_ARENA() public: @@ -28,10 +27,10 @@ class Session : public std::enable_shared_from_this virtual ~Session(); public: void Run(std::shared_ptr sock); - Socket GetSocket(); + std::shared_ptr GetSocket(); public: void Disconnect(); - void SendUnsafe(std::span buffer); + void SendUnsafe(std::span buffer) const; void SendAtomic(std::span buffer); void Send(Packet* packet, bool unsafe = false); public: @@ -45,11 +44,8 @@ class Session : public std::enable_shared_from_this void OnRecvCompleted(Context* context, bool isSuccess); void OnSendCompleted(Context* context, bool isSuccess); private: - std::shared_ptr m_ref; // TEMP - std::vector m_buffer; net::Context m_recvCtx; net::Context m_sendCtx; std::atomic m_isSending; - std::atomic m_isDisconnected; }; \ No newline at end of file diff --git a/Core/include/Subsystem/Database.hpp b/Core/include/Subsystem/Database.hpp new file mode 100644 index 0000000..4fc019f --- /dev/null +++ b/Core/include/Subsystem/Database.hpp @@ -0,0 +1,159 @@ +#pragma once +#include +#include + +#include "cppconn/driver.h" +#include "cppconn/prepared_statement.h" +#include "cppconn/resultset.h" + +#include "Functor.hpp" + +class AsyncStatement; + +class SVENGINE_API Database +{ + friend AsyncStatement; +public: + Database(); + ~Database(); +public: + void Initialize(); +public: + void SetDatabaseProfile(StringView username, StringView password, StringView dbname); + void CreateConnection(); + + template + std::unique_ptr CreateStatement(const char* formattedSql, Args... args) + { + auto conn = PopConnection(); + + auto pstmt = std::shared_ptr( + static_cast(conn->prepareStatement( + std::format(formattedSql, args...) + )) + ); + return pstmt; + } + + template + std::unique_ptr CallProcedure(const char* procedure, Args... args) + { + auto conn = PopConnection(); + + try { + auto pstmt = std::unique_ptr( + static_cast(conn->prepareStatement( + std::format("CALL {}({})", + procedure, concatenate(args...) + ) + )) + ); + return pstmt; + } + catch (std::exception& e) + { + Console::Error(Category::Database, ToUnicodeString(e.what())); + return nullptr; + } + } +private: + std::shared_ptr PopConnection(); + void ReturnConnection(sql::Connection* conn); +private: + template + struct is_string + : std::false_type + {}; + + template + struct is_string> + : std::true_type + {}; + + template + void concatArgs(std::stringstream& ss, T first, Args... args) { + if constexpr (is_string::value) + first = std::format("'{}'", first); + ss << first; + if constexpr (sizeof...(args) > 0) { + ss << ", "; + concatArgs(ss, args...); + } + } + + template + std::string concatenate(Args... args) { + std::stringstream ss; + concatArgs(ss, args...); + return ss.str(); + } +private: + String m_dbUserName; + String m_dbPwd; + String m_dbName; + uint32 m_maxConnectionCount = 10; + sql::Driver* m_driver; + List> m_connections; + bool m_destroyed; +}; + +extern Database* GDatabase; + +class AsyncStatement : public sql::PreparedStatement +{ +public: + std::future AsyncExecute(std::function callback = [](bool) {}) + { + return std::async(std::launch::async, [this, callback] { + try + { + auto res = this->execute(); + callback(res); + return res; + } + catch (std::exception& e) + { + Console::Error(Category::Database, ToUnicodeString(e.what())); + ASSERT_CRASH(false); + return false; + } + }); + } + + std::future AsyncUpdate(std::function callback = [](int) {}) + { + return std::async(std::launch::async, [this, callback] { + try + { + auto res = this->executeUpdate(); + callback(res); + return res; + } + catch (std::exception& e) + { + Console::Error(Category::Database, ToUnicodeString(e.what())); + ASSERT_CRASH(false); + return 0; + } + }); + } + + std::future> AsyncQuery(std::function)> callback = + [](std::shared_ptr) {}) + { + return std::async(std::launch::async, [this, callback] { + try + { + auto res = std::shared_ptr(this->executeQuery()); + callback(res); + return res; + } + catch (std::exception& e) + { + Console::Error(Category::Database, ToUnicodeString(e.what())); + ASSERT_CRASH(false); + return static_cast>(nullptr); + } + }); + } +}; \ No newline at end of file diff --git a/Core/include/Subsystem/Engine.hpp b/Core/include/Subsystem/Engine.hpp new file mode 100644 index 0000000..71bb5af --- /dev/null +++ b/Core/include/Subsystem/Engine.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "Functor.hpp" + +class SVENGINE_API Engine { + enum EngineOption + { + WorkTick = 10, + }; +public: + Engine(); + ~Engine(); +public: + void Initialize(); + + void Run(int32 io); + + + template + void Launch(void(T::* method)(Args...), T* ptr, Args... args) + { + auto functor = MakeShared(method, ptr, args...); + m_funcProc->Push(functor); + } + + template + void Launch(uint64 delay, void(T::* method)(Args...), T* ptr, Args... args) + { + auto functor = MakeShared(method, ptr, args...); + m_funcProc->Push(delay, functor); + } +private: + void ProcessIo(int32 count); + void ProcessLogic(); +private: + std::unique_ptr m_funcProc; +}; + +extern Engine* GEngine; + +template +struct Runnable +{ + template + void Run(void(T::* method)(Args...), Args... args) + { + GEngine->Launch(method, static_cast(this), args...); + } + + template + void Run(uint64 delay, void(T::* method)(Args...), Args... args) + { + GEngine->Launch(delay, method, static_cast(this), args...); + } +}; \ No newline at end of file diff --git a/Core/include/Subsystem/GameInstance.hpp b/Core/include/Subsystem/GameInstance.hpp new file mode 100644 index 0000000..8ea7863 --- /dev/null +++ b/Core/include/Subsystem/GameInstance.hpp @@ -0,0 +1,7 @@ +#pragma once + +class GameInstance +{ +public: + virtual void Run() = 0; +}; \ No newline at end of file diff --git a/SvEngine/include/util/Types.hpp b/Core/include/Types.hpp similarity index 83% rename from SvEngine/include/util/Types.hpp rename to Core/include/Types.hpp index 0a0adfb..bbae5cf 100644 --- a/SvEngine/include/util/Types.hpp +++ b/Core/include/Types.hpp @@ -73,20 +73,4 @@ template using ConcurrencyHashSet = tbb::concurrent_unordered_set; using String = std::wstring; -using StringView = std::wstring_view; - -#define CRASH() \ -{ \ - int* crash = nullptr; \ - __analysis_assume(crash != nullptr); \ - *crash = 0xDEAD; \ -} -#define ASSERT_CRASH(expr) \ -{ \ - if(!(expr)) \ - { \ - CRASH(); \ - __analysis_assume(expr); \ - } \ -} -#define MAKE_LOG_CATEGORY(name) namespace Category { static String name(L#name); } \ No newline at end of file +using StringView = std::wstring_view; \ No newline at end of file diff --git a/SvEngine/include/util/Console.hpp b/Core/include/Util/Console.hpp similarity index 97% rename from SvEngine/include/util/Console.hpp rename to Core/include/Util/Console.hpp index 9012196..5492c0f 100644 --- a/SvEngine/include/util/Console.hpp +++ b/Core/include/Util/Console.hpp @@ -46,7 +46,7 @@ enum EncodingType { UTF8, }; -class Console { +class SVENGINE_API Console { friend class Engine; static void Initialize(); diff --git a/SvEngine/include/util/File.hpp b/Core/include/Util/File.hpp similarity index 89% rename from SvEngine/include/util/File.hpp rename to Core/include/Util/File.hpp index 611ea5e..01fe5bc 100644 --- a/SvEngine/include/util/File.hpp +++ b/Core/include/Util/File.hpp @@ -4,7 +4,7 @@ namespace fs = std::filesystem; -class File +class SVENGINE_API File { public: File(StringView path); diff --git a/SvEngine/include/util/Math.hpp b/Core/include/Util/Math.hpp similarity index 89% rename from SvEngine/include/util/Math.hpp rename to Core/include/Util/Math.hpp index 23588aa..3f20f36 100644 --- a/SvEngine/include/util/Math.hpp +++ b/Core/include/Util/Math.hpp @@ -1,6 +1,6 @@ #pragma once -class Math +class SVENGINE_API Math { public: static float Round(float x, int32 p = 0); diff --git a/SvEngine/include/util/Parser/Ini.hpp b/Core/include/Util/Parser/Ini.hpp similarity index 94% rename from SvEngine/include/util/Parser/Ini.hpp rename to Core/include/Util/Parser/Ini.hpp index 2fc0a8b..a6a105f 100644 --- a/SvEngine/include/util/Parser/Ini.hpp +++ b/Core/include/Util/Parser/Ini.hpp @@ -2,9 +2,9 @@ #include "CoreHeader.hpp" -class Ini +class SVENGINE_API Ini { - class Section + class SVENGINE_API Section { public: Section(StringView filename, StringView section); diff --git a/SvEngine/include/util/Random.hpp b/Core/include/Util/Random.hpp similarity index 93% rename from SvEngine/include/util/Random.hpp rename to Core/include/Util/Random.hpp index 8565aa4..a672535 100644 --- a/SvEngine/include/util/Random.hpp +++ b/Core/include/Util/Random.hpp @@ -2,7 +2,7 @@ #include -class Random +class SVENGINE_API Random { public: template diff --git a/Core/include/Util/String.hpp b/Core/include/Util/String.hpp new file mode 100644 index 0000000..898616f --- /dev/null +++ b/Core/include/Util/String.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "Types.hpp" +#include + +SVENGINE_API String ToUnicodeString(std::string_view str); + +SVENGINE_API std::string ToAnsiString(StringView str); + +SVENGINE_API String UUIDv4() noexcept; + +SVENGINE_API String Timestamp(); + +SVENGINE_API Vector Split(StringView str, WCHAR del); \ No newline at end of file diff --git a/SvEngine/include/util/Template.hpp b/Core/include/Util/Template.hpp similarity index 64% rename from SvEngine/include/util/Template.hpp rename to Core/include/Util/Template.hpp index 1139145..d6f95a8 100644 --- a/SvEngine/include/util/Template.hpp +++ b/Core/include/Util/Template.hpp @@ -1,5 +1,4 @@ #pragma once - #include #include @@ -23,4 +22,16 @@ static inline std::shared_ptr MakeShared(const size_t size) { using Ty = PeelArrayType::type; return std::shared_ptr(new Ty[size]); +} + +template requires std::is_class_v +static inline std::unique_ptr MakeUnique(Args&&... args) +{ + return std::unique_ptr(new T(std::forward(args)...)); +} +template requires std::is_unbounded_array_v +static inline std::unique_ptr MakeUnique(const size_t size) +{ + using Ty = PeelArrayType::type; + return std::unique_ptr(new Ty[size]); } \ No newline at end of file diff --git a/Core/src/Functor.cpp b/Core/src/Functor.cpp new file mode 100644 index 0000000..dcaf417 --- /dev/null +++ b/Core/src/Functor.cpp @@ -0,0 +1,66 @@ +#include "pch.h" +#include "Functor.hpp" + +Functor::~Functor() noexcept +{ +} + +Functor::Functor(CallbackType functor) +{ + functor = functor; +} + +DelayedFunctor::DelayedFunctor(uint64 execTime, std::shared_ptr functor) + : execTime(execTime), functor(functor) +{ +} + +bool DelayedFunctor::operator<(const DelayedFunctor& other) const +{ + return execTime < other.execTime; +} + +bool DelayedFunctor::operator>(const DelayedFunctor& other) const +{ + return execTime > other.execTime; +} + +void FunctorProcessor::Push(std::shared_ptr functor) +{ + m_functorQue.push(functor); +} + +void FunctorProcessor::Push(uint64 delay, std::shared_ptr functor) +{ + m_delayedFuncQue.push(DelayedFunctor(GetTickCount64() + delay, functor)); +} + +void FunctorProcessor::Flush() +{ + while (!m_functorQue.empty()) + { + std::shared_ptr functor; + if (m_functorQue.try_pop(functor)) + (*functor)(); + } +} + +void FunctorProcessor::Fetch() +{ + while (!m_delayedFuncQue.empty()) + { + DelayedFunctor delayedFunc; + if (m_delayedFuncQue.try_pop(delayedFunc)) + { + if (GetTickCount64() < delayedFunc.execTime) + { + m_delayedFuncQue.push(delayedFunc); + break; + } + else + { + m_functorQue.push(delayedFunc.functor); + } + } + } +} diff --git a/SvEngine/src/GameFramework/Vector.cpp b/Core/src/GameFramework/Vector.cpp similarity index 100% rename from SvEngine/src/GameFramework/Vector.cpp rename to Core/src/GameFramework/Vector.cpp diff --git a/SvEngine/src/Memory/Arena.cpp b/Core/src/Memory/Arena.cpp similarity index 100% rename from SvEngine/src/Memory/Arena.cpp rename to Core/src/Memory/Arena.cpp diff --git a/SvEngine/src/Memory/ObjectPool.cpp b/Core/src/Memory/ObjectPool.cpp similarity index 100% rename from SvEngine/src/Memory/ObjectPool.cpp rename to Core/src/Memory/ObjectPool.cpp diff --git a/SvEngine/src/Network/Client.cpp b/Core/src/Network/Client.cpp similarity index 73% rename from SvEngine/src/Network/Client.cpp rename to Core/src/Network/Client.cpp index 0e7ac0a..cec72bb 100644 --- a/SvEngine/src/Network/Client.cpp +++ b/Core/src/Network/Client.cpp @@ -26,11 +26,11 @@ void Client::OnConnectCompleted(Context*, bool isSuccess) { if (isSuccess) { client->Run(std::make_unique(m_sock)); - // SOCKADDR_IN addr; - // int len = sizeof(addr); - // if (SOCKET_ERROR == getpeername(client->m_sosck->getHandle(), reinterpret_cast(&addr), &len)) - // throw net::network_error("getpeername()"); - client->OnConnected(Endpoint()); + SOCKADDR_IN addr; + int len = sizeof(addr); + if (SOCKET_ERROR == getpeername(client->m_sock->getHandle(), reinterpret_cast(&addr), &len)) + throw net::network_error("getpeername()"); + client->OnConnected(Endpoint::parse(addr)); } else client->OnFail(Failure::Connect); diff --git a/SvEngine/src/Network/Packet.cpp b/Core/src/Network/Packet.cpp similarity index 98% rename from SvEngine/src/Network/Packet.cpp rename to Core/src/Network/Packet.cpp index 3195473..255d0f8 100644 --- a/SvEngine/src/Network/Packet.cpp +++ b/Core/src/Network/Packet.cpp @@ -26,6 +26,11 @@ void Packet::Parse(std::span buffer) { Read(); } +uint16 Packet::GetPacketId(std::span buffer) +{ + return *reinterpret_cast(buffer.data()); +} + void Packet::Read() { *this >> m_id; } diff --git a/SvEngine/src/Network/Server.cpp b/Core/src/Network/Server.cpp similarity index 100% rename from SvEngine/src/Network/Server.cpp rename to Core/src/Network/Server.cpp diff --git a/SvEngine/src/Network/Session.cpp b/Core/src/Network/Session.cpp similarity index 76% rename from SvEngine/src/Network/Session.cpp rename to Core/src/Network/Session.cpp index b5a62d7..ef776ee 100644 --- a/SvEngine/src/Network/Session.cpp +++ b/Core/src/Network/Session.cpp @@ -10,7 +10,8 @@ CREATE_ARENA(Session, 0x1000) -Session::Session() : m_buffer(0x10000, '\0'), m_isDisconnected(false), m_isSending(false) { +Session::Session() : m_buffer(0x10000, '\0'), m_isSending(false) +{ } void Session::Run(std::shared_ptr sock) { @@ -21,10 +22,10 @@ void Session::Run(std::shared_ptr sock) { m_sendCtx.completed = bind(&Session::OnSendCompleted, this, std::placeholders::_1, std::placeholders::_2); m_sock->receive(&m_recvCtx); - m_ref = shared_from_this(); } -void Session::OnRecvCompleted(Context *context, bool isSuccess) { +void Session::OnRecvCompleted(Context *context, bool isSuccess) +{ if(!isSuccess || context->length == 0) { Disconnect(); return; @@ -40,25 +41,26 @@ void Session::OnSendCompleted(Context*, bool isSuccess) auto endpoint = m_sock->getRemoteEndpoint(); if (endpoint.has_value()) OnDisconnected(endpoint.value()); + delete this; } } -Session::~Session() { +Session::~Session() +{ } -void Session::Disconnect() { - if (!m_isDisconnected.exchange(true)) - { - OnDisconnected(m_sock->getRemoteEndpoint().value()); - m_ref = nullptr; - } +void Session::Disconnect() +{ + OnDisconnected(m_sock->getRemoteEndpoint().value()); + delete this; } -Socket Session::GetSocket() { - return *m_sock; +std::shared_ptr Session::GetSocket() +{ + return m_sock; } -void Session::SendUnsafe(std::span buffer) +void Session::SendUnsafe(std::span buffer) const { m_sock->send(buffer); } diff --git a/Core/src/Subsystem/Database.cpp b/Core/src/Subsystem/Database.cpp new file mode 100644 index 0000000..0ff8060 --- /dev/null +++ b/Core/src/Subsystem/Database.cpp @@ -0,0 +1,74 @@ +#include "pch.h" +#include "Subsystem/Database.hpp" + +void Database::CreateConnection() +{ + for (uint32 i = 0; i < m_maxConnectionCount; ++i) + { + try { + auto conn = std::shared_ptr( + m_driver->connect("tcp://localhost:3306", + ToAnsiString(m_dbUserName), + ToAnsiString(m_dbPwd) + ), + std::bind(&Database::ReturnConnection, this, std::placeholders::_1) + ); + conn->setSchema(ToAnsiString(m_dbName)); + m_connections.emplace_back(conn); + } + catch (std::exception&) { + Console::Error(Category::Database, TEXT("Could not connect to specified database profile.")); + } + } +} + +std::shared_ptr Database::PopConnection() +{ + if (m_connections.empty()) + { + m_maxConnectionCount *= 2; + CreateConnection(); + } + + std::shared_ptr conn = m_connections.front(); + m_connections.pop_front(); + + return conn; +} + +void Database::ReturnConnection(sql::Connection* conn) +{ + if (m_destroyed) + delete conn; + else { + m_connections.emplace_back(conn, [this](sql::Connection* conn) { + ReturnConnection(conn); + }); + } +} + +Database::Database() : m_destroyed(false) +{ + m_driver = nullptr; + m_dbUserName = TEXT(""); + m_dbPwd = TEXT(""); + m_dbName = TEXT(""); +} + +Database::~Database() +{ + m_destroyed = true; + m_connections.clear(); +} + +void Database::Initialize() +{ + m_driver = get_driver_instance(); +} + +void Database::SetDatabaseProfile(StringView username, StringView password, StringView dbname) +{ + m_dbUserName = username; + m_dbPwd = password; + m_dbName = dbname; +} \ No newline at end of file diff --git a/Core/src/Subsystem/Engine.cpp b/Core/src/Subsystem/Engine.cpp new file mode 100644 index 0000000..312b210 --- /dev/null +++ b/Core/src/Subsystem/Engine.cpp @@ -0,0 +1,50 @@ +#include "pch.h" +#include "Subsystem/Engine.hpp" + +Engine::Engine() + : m_funcProc(std::make_unique()) +{ + Console::Initialize(); + + net::Option::Autorun = false; +} + +Engine::~Engine() +{ +} + +void Engine::Run(int32 io) +{ + ProcessIo(io); + auto logic = new std::thread(&Engine::ProcessLogic, this); + logic->join(); +} + +void Engine::Initialize() +{ +} + +void Engine::ProcessIo(int32 count) +{ + for (int32 i = 0; i < count; ++i) + { + new std::thread([] { + { + while (true) + { + IoSystem::instance().worker(); // IOCP I/O Worker + } + } + }); + } +} + +void Engine::ProcessLogic() +{ + while (true) + { + m_funcProc->Fetch(); + m_funcProc->Flush(); + std::this_thread::sleep_for(std::chrono::milliseconds(WorkTick)); + } +} diff --git a/SvEngine/src/util/Console.cpp b/Core/src/Util/Console.cpp similarity index 100% rename from SvEngine/src/util/Console.cpp rename to Core/src/Util/Console.cpp diff --git a/SvEngine/src/util/File.cpp b/Core/src/Util/File.cpp similarity index 100% rename from SvEngine/src/util/File.cpp rename to Core/src/Util/File.cpp diff --git a/SvEngine/src/util/Math.cpp b/Core/src/Util/Math.cpp similarity index 100% rename from SvEngine/src/util/Math.cpp rename to Core/src/Util/Math.cpp diff --git a/SvEngine/src/util/Parser/Ini.cpp b/Core/src/Util/Parser/Ini.cpp similarity index 100% rename from SvEngine/src/util/Parser/Ini.cpp rename to Core/src/Util/Parser/Ini.cpp diff --git a/SvEngine/src/util/String.cpp b/Core/src/Util/String.cpp similarity index 100% rename from SvEngine/src/util/String.cpp rename to Core/src/Util/String.cpp diff --git a/Engine.sln b/Engine.sln index 1c26945..b9b2555 100644 --- a/Engine.sln +++ b/Engine.sln @@ -2,8 +2,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34309.116 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SvEngine", "SvEngine\SvEngine.vcxproj", "{0E19D820-B6BE-4D23-805B-AAD9EF0EEA69}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{D38E0D41-FFF8-4938-AD80-3AB93233CB2B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine", "Engine", "{87A20E2A-BD72-441B-AE36-81CB51748EBB}" @@ -13,12 +11,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .gitignore = .gitignore .gitmodules = .gitmodules README.md = README.md + setup.bat = setup.bat EndProjectSection EndProject Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "PacketGenerator", "tools\PacketGenerator\PacketGenerator.pyproj", "{1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server", "Server", "{796B2721-0044-4FB0-9296-9D2ABA42E3F6}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SvEngine", "Core\SvEngine.vcxproj", "{0E19D820-B6BE-4D23-805B-AAD9EF0EEA69}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -29,6 +30,12 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Debug|x64.ActiveCfg = Debug|Any CPU + {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Debug|x86.ActiveCfg = Debug|Any CPU + {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Release|x64.ActiveCfg = Release|Any CPU + {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Release|x86.ActiveCfg = Release|Any CPU {0E19D820-B6BE-4D23-805B-AAD9EF0EEA69}.Debug|Any CPU.ActiveCfg = Debug|x64 {0E19D820-B6BE-4D23-805B-AAD9EF0EEA69}.Debug|Any CPU.Build.0 = Debug|x64 {0E19D820-B6BE-4D23-805B-AAD9EF0EEA69}.Debug|x64.ActiveCfg = Debug|x64 @@ -41,18 +48,12 @@ Global {0E19D820-B6BE-4D23-805B-AAD9EF0EEA69}.Release|x64.Build.0 = Release|x64 {0E19D820-B6BE-4D23-805B-AAD9EF0EEA69}.Release|x86.ActiveCfg = Release|Win32 {0E19D820-B6BE-4D23-805B-AAD9EF0EEA69}.Release|x86.Build.0 = Release|Win32 - {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Debug|x64.ActiveCfg = Debug|Any CPU - {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Debug|x86.ActiveCfg = Debug|Any CPU - {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Release|x64.ActiveCfg = Release|Any CPU - {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {0E19D820-B6BE-4D23-805B-AAD9EF0EEA69} = {87A20E2A-BD72-441B-AE36-81CB51748EBB} {1CBC2443-D0A8-4ED5-AC39-1782D2001B4E} = {D38E0D41-FFF8-4938-AD80-3AB93233CB2B} + {0E19D820-B6BE-4D23-805B-AAD9EF0EEA69} = {87A20E2A-BD72-441B-AE36-81CB51748EBB} EndGlobalSection EndGlobal diff --git a/Libraries/mysql-connector/INFO_BIN b/Libraries/mysql-connector/INFO_BIN new file mode 100644 index 0000000..874ef33 --- /dev/null +++ b/Libraries/mysql-connector/INFO_BIN @@ -0,0 +1,8 @@ +MySQL Connector/C++ Build Information + +build-date : 2024-06-16 +os-info : Windows-10.0.20348 +compiler : MSVC 19.16.27051.0 +protobuf-version : 3.6.1 +build-type : RelWithDebInfo + diff --git a/Libraries/mysql-connector/INFO_SRC b/Libraries/mysql-connector/INFO_SRC new file mode 100644 index 0000000..c4764e7 --- /dev/null +++ b/Libraries/mysql-connector/INFO_SRC @@ -0,0 +1,7 @@ +MySQL Connector/C++ Sources Information + +version : 9.0.0 +branch : release/9.0.0 +commit : b01fa1ec05e0717a50d0950d21baa364481d5afb +short : b01fa1ec + diff --git a/Libraries/mysql-connector/LICENSE.txt b/Libraries/mysql-connector/LICENSE.txt new file mode 100644 index 0000000..a584cb4 --- /dev/null +++ b/Libraries/mysql-connector/LICENSE.txt @@ -0,0 +1,3085 @@ +Licensing Information User Manual + +MySQL Connector/C++ 9.0.0 Community + __________________________________________________________________ + +Introduction + + This License Information User Manual contains Oracle's product license + and other licensing information, including licensing information for + third-party software which may be included in this distribution of + MySQL Connector/C++ 9.0.0 Community. + + Last updated: May 2024 + +Licensing Information + + This release of MySQL Connector/C++ 9.0.0 Community is brought to you + by the MySQL team at Oracle. This software is released under version 2 + of the GNU General Public License (GPLv2), as set forth below, with the + following additional permissions: + + This distribution of MySQL Connector/C++ 9.0.0 Community is designed to + work with certain software (including but not limited to OpenSSL) that + is licensed under separate terms, as designated in a particular file or + component or in the license documentation. Without limiting your rights + under the GPLv2, the authors of MySQL hereby grant you an additional + permission to link the program and your derivative works with the + separately licensed software that they have either included with the + program or referenced in the documentation. + + Without limiting the foregoing grant of rights under the GPLv2 and + additional permission as to separately licensed software, this + Connector is also subject to the Universal FOSS Exception, version 1.0, + a copy of which is reproduced below and can also be found along with + its FAQ at http://oss.oracle.com/licenses/universal-foss-exception. + + Copyright (c) 2008, 2024, Oracle and/or its affiliates. + +Election of GPLv2 + + For the avoidance of doubt, except that if any license choice other + than GPL or LGPL is available it will apply instead, Oracle elects to + use only the General Public License version 2 (GPLv2) at this time for + any software where a choice of GPL license versions is made available + with the language indicating that GPLv2 or any later version may be + used, or where a choice of which version of the GPL is applied is + otherwise unspecified. + +GNU General Public License Version 2.0, June 1991 + +The following applies to all products licensed under the GNU General +Public License, Version 2.0: You may not use the identified files +except in compliance with the GNU General Public License, Version +2.0 (the "License.") You may obtain a copy of the License at +http://www.gnu.org/licenses/gpl-2.0.txt. A copy of the license is +also reproduced below. Unless required by applicable law or agreed +to in writing, software distributed under the License is distributed +on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +either express or implied. See the License for the specific language +governing permissions and limitations under the License. + + + ====================================================================== + ====================================================================== + + +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +Everyone is permitted to copy and distribute verbatim +copies of this license document, but changing it is not +allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, +and (2) offer you this license which gives you legal permission to +copy, distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, +we want its recipients to know that what they have is not the original, +so that any problems introduced by others will not reflect on the +original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software + interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as +a special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new +versions of the General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a +version number of this License, you may choose any version ever +published by the Free Software Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS +WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details + type 'show w'. This is free software, and you are welcome + to redistribute it under certain conditions; type 'show c' + for details. + +The hypothetical commands 'show w' and 'show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than 'show w' and +'show c'; they could even be mouse-clicks or menu items--whatever +suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program 'Gnomovision' (which makes passes at compilers) written + by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, +you may consider it more useful to permit linking proprietary +applications with the library. If this is what you want to do, use +the GNU Lesser General Public License instead of this License. + + ====================================================================== + ====================================================================== + +The Universal FOSS Exception, Version 1.0 + + In addition to the rights set forth in the other license(s) included in + the distribution for this software, data, and/or documentation + (collectively the "Software", and such licenses collectively with this + additional permission the "Software License"), the copyright holders + wish to facilitate interoperability with other software, data, and/or + documentation distributed with complete corresponding source under a + license that is OSI-approved and/or categorized by the FSF as free + (collectively "Other FOSS"). We therefore hereby grant the following + additional permission with respect to the use and distribution of the + Software with Other FOSS, and the constants, function signatures, data + structures and other invocation methods used to run or interact with + each of them (as to each, such software's "Interfaces"): + + i. The Software's Interfaces may, to the extent permitted by the + license of the Other FOSS, be copied into, used and distributed in + the Other FOSS in order to enable interoperability, without + requiring a change to the license of the Other FOSS other than as + to any Interfaces of the Software embedded therein. The Software's + Interfaces remain at all times under the Software License, + including without limitation as used in the Other FOSS (which upon + any such use also then contains a portion of the Software under the + Software License). + + ii. The Other FOSS's Interfaces may, to the extent permitted by the + license of the Other FOSS, be copied into, used and distributed in + the Software in order to enable interoperability, without requiring + that such Interfaces be licensed under the terms of the Software + License or otherwise altering their original terms, if this does + not require any portion of the Software other than such Interfaces + to be licensed under the terms other than the Software License. + + iii. If only Interfaces and no other code is copied between the + Software and the Other FOSS in either direction, the use and/or + distribution of the Software with the Other FOSS shall not be + deemed to require that the Other FOSS be licensed under the license + of the Software, other than as to any Interfaces of the Software + copied into the Other FOSS. This includes, by way of example and + without limitation, statically or dynamically linking the Software + together with Other FOSS after enabling interoperability using the + Interfaces of one or both, and distributing the resulting + combination under different licenses for the respective portions + thereof. + + For avoidance of doubt, a license which is OSI-approved or + categorized by the FSF as free, includes, for the purpose of this + permission, such licenses with additional permissions, and any + license that has previously been so approved or categorized as + free, even if now deprecated or otherwise no longer recognized as + approved or free. Nothing in this additional permission grants any + right to distribute any portion of the Software on terms other than + those of the Software License or grants any additional permission + of any kind for use or distribution of the Software in conjunction + with software other than Other FOSS. + + ====================================================================== + ====================================================================== + +Licenses for Third-Party Components + + The following sections contain licensing information for libraries that + may be included with this product. We are thankful to all individuals + that have created these. Standard licenses referenced herein are + detailed in the Standard Licenses section. + +Cyrus SASL + + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 +* tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +The following files + +./lib + saslint.h auxprop.c canonusr.c checkpw.c client.c common.c config.c + external.c saslutil.c server.c seterror.c dlopen.c +./plugins + scram.c gssapi.c +./common + plugin_common.c + +have a license header similar to the above with the following copyright: +/* + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. + * + +./lib/md5.c includes the following license header: +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm +*/ + +/* Function names changed to avoid namespace collisions: Rob Siemborski */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*/ + + ====================================================================== + ====================================================================== + +Google Protocol Buffers + +Copyright 2008 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. + +4th party - abseil-cpp +---------------------- + +=== Header in source files: +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// This header file contains C++11 versions of standard header +// abstractions available within C++14 and C++17, and are designed to be +// drop-in replacement for code compliant with C++14 and C++17. + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + +A copy of the Apache License v2.0, January 2004 license can be found +in the 'Standard Licenses' section. + + ====================================================================== + ====================================================================== + +Kerberos5 + +Kerberos5 + +Copyright (C) 1985-2019 by the Massachusetts Institute of Technology. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Downloading of this software may constitute an export of cryptographic +software from the United States of America that is subject to the +United States Export Administration Regulations (EAR), 15 CFR 730-774. +Additional laws or regulations may apply. It is the responsibility of +the person or entity contemplating export to comply with all +applicable export laws and regulations, including obtaining any +required license from the U.S. government. + +The U.S. government prohibits export of encryption source code to +certain countries and individuals, including, but not limited to, the +countries of Cuba, Iran, North Korea, Sudan, Syria, and residents and +nationals of those countries. + +Documentation components of this software distribution are licensed +under a Creative Commons Attribution-ShareAlike 3.0 Unported License. +(http://creativecommons.org/licenses/by-sa/3.0/) + +Individual source code files are copyright MIT, Cygnus Support, +Novell, OpenVision Technologies, Oracle, Red Hat, Sun Microsystems, +FundsXpress, and others. + +Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, +and Zephyr are trademarks of the Massachusetts Institute of Technology +(MIT). No commercial use of these trademarks may be made without +prior written permission of MIT. + +"Commercial use" means use of a name in a product or other for-profit +manner. It does NOT prevent a commercial firm from referring to the +MIT trademarks in order to convey information (although in doing so, +recognition of their trademark status should be given). + +====================================================================== + +The following copyright and permission notice applies to the +OpenVision Kerberos Administration system located in "kadmin/create", +"kadmin/dbutil", "kadmin/passwd", "kadmin/server", "lib/kadm5", and +portions of "lib/rpc": + + Copyright, OpenVision Technologies, Inc., 1993-1996, All Rights + Reserved + + WARNING: Retrieving the OpenVision Kerberos Administration system + source code, as described below, indicates your acceptance of the + following terms. If you do not agree to the following terms, do + not retrieve the OpenVision Kerberos administration system. + + You may freely use and distribute the Source Code and Object Code + compiled from it, with or without modification, but this Source + Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY, + INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR + FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER + EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY + FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, + WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE + CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY + OTHER REASON. + + OpenVision retains all copyrights in the donated Source Code. + OpenVision also retains copyright to derivative works of the Source + Code, whether created by OpenVision or by a third party. The + OpenVision copyright notice must be preserved if derivative works + are made based on the donated Source Code. + + OpenVision Technologies, Inc. has donated this Kerberos + Administration system to MIT for inclusion in the standard Kerberos + 5 distribution. This donation underscores our commitment to + continuing Kerberos technology development and our gratitude for + the valuable work which has been performed by MIT and the Kerberos + community. + +====================================================================== + + Portions contributed by Matt Crawford "crawdad@fnal.gov" were work +performed at Fermi National Accelerator Laboratory, which is + operated by Universities Research Association, Inc., under contract + DE-AC02-76CHO3000 with the U.S. Department of Energy. + +====================================================================== + +Portions of "src/lib/crypto" have the following copyright: + + Copyright (C) 1998 by the FundsXpress, INC. + + All rights reserved. + + Export of this software from the United States of America may + require a specific license from the United States Government. + It is the responsibility of any person or organization + contemplating export to obtain such a license before exporting. + + WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + distribute this software and its documentation for any purpose and + without fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation, and that + the name of FundsXpress. not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. FundsXpress makes no representations + about the suitability of this software for any purpose. It is + provided "as is" without express or implied warranty. + + THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +====================================================================== + +The implementation of the AES encryption algorithm in +"src/lib/crypto/builtin/aes" has the following copyright: + + Copyright (C) 2001, Dr Brian Gladman "brg@gladman.uk.net", Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and + binary form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + DISCLAIMER + + This software is provided 'as is' with no explcit or implied + warranties in respect of any properties, including, but not limited + to, correctness and fitness for purpose. + +====================================================================== + +Portions contributed by Red Hat, including the pre-authentication +plug-in framework and the NSS crypto implementation, contain the +following copyright: + + Copyright (C) 2006 Red Hat, Inc. + Portions copyright (C) 2006 Massachusetts Institute of Technology + All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Red Hat, Inc., nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +====================================================================== + +The bundled verto source code is subject to the following license: + + Copyright 2011 Red Hat, Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + +====================================================================== + +The MS-KKDCP client implementation has the following copyright: + + Copyright 2013,2014 Red Hat, Inc. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +====================================================================== + +The implementations of GSSAPI mechglue in GSSAPI-SPNEGO in +"src/lib/gssapi", including the following files: + + lib/gssapi/generic/gssapi_err_generic.et + lib/gssapi/mechglue/g_accept_sec_context.c + lib/gssapi/mechglue/g_acquire_cred.c + lib/gssapi/mechglue/g_canon_name.c + lib/gssapi/mechglue/g_compare_name.c + lib/gssapi/mechglue/g_context_time.c + lib/gssapi/mechglue/g_delete_sec_context.c + lib/gssapi/mechglue/g_dsp_name.c + lib/gssapi/mechglue/g_dsp_status.c + lib/gssapi/mechglue/g_dup_name.c + lib/gssapi/mechglue/g_exp_sec_context.c + lib/gssapi/mechglue/g_export_name.c + lib/gssapi/mechglue/g_glue.c + lib/gssapi/mechglue/g_imp_name.c + lib/gssapi/mechglue/g_imp_sec_context.c + lib/gssapi/mechglue/g_init_sec_context.c + lib/gssapi/mechglue/g_initialize.c + lib/gssapi/mechglue/g_inquire_context.c + lib/gssapi/mechglue/g_inquire_cred.c + lib/gssapi/mechglue/g_inquire_names.c + lib/gssapi/mechglue/g_process_context.c + lib/gssapi/mechglue/g_rel_buffer.c + lib/gssapi/mechglue/g_rel_cred.c + lib/gssapi/mechglue/g_rel_name.c + lib/gssapi/mechglue/g_rel_oid_set.c + lib/gssapi/mechglue/g_seal.c + lib/gssapi/mechglue/g_sign.c + lib/gssapi/mechglue/g_store_cred.c + lib/gssapi/mechglue/g_unseal.c + lib/gssapi/mechglue/g_userok.c + lib/gssapi/mechglue/g_utils.c + lib/gssapi/mechglue/g_verify.c + lib/gssapi/mechglue/gssd_pname_to_uid.c + lib/gssapi/mechglue/mglueP.h + lib/gssapi/mechglue/oid_ops.c + lib/gssapi/spnego/gssapiP_spnego.h + lib/gssapi/spnego/spnego_mech.c + +and the initial implementation of incremental propagation, including +the following new or changed files: + + include/iprop_hdr.h + kadmin/server/ipropd_svc.c + lib/kdb/iprop.x + lib/kdb/kdb_convert.c + lib/kdb/kdb_log.c + lib/kdb/kdb_log.h + lib/krb5/error_tables/kdb5_err.et + slave/kpropd_rpc.c + slave/kproplog.c + +are subject to the following license: + + Copyright (C) 2004 Sun Microsystems, Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +====================================================================== + +Kerberos V5 includes documentation and software developed at the +University of California at Berkeley, which includes this copyright +notice: + + Copyright (C) 1983 Regents of the University of California. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +====================================================================== + +Portions contributed by Novell, Inc., including the LDAP database +backend, are subject to the following license: + + Copyright (C) 2004-2005, Novell, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * The copyright holder's name is not used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +====================================================================== + +Portions funded by Sandia National Laboratory and developed by the +University of Michigan's Center for Information Technology +Integration, including the PKINIT implementation, are subject to the +following license: + + COPYRIGHT (C) 2006-2007 + THE REGENTS OF THE UNIVERSITY OF MICHIGAN + ALL RIGHTS RESERVED + + Permission is granted to use, copy, create derivative works and + redistribute this software and such derivative works for any + purpose, so long as the name of The University of Michigan is not + used in any advertising or publicity pertaining to the use of + distribution of this software without specific, written prior + authorization. If the above copyright notice or any other + identification of the University of Michigan is included in any + copy of any portion of this software, then the disclaimer below + must also be included. + + THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE + UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND + WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER + EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR + ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR + IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR + IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +====================================================================== + +The pkcs11.h file included in the PKINIT code has the following +license: + + Copyright 2006 g10 Code GmbH + Copyright 2006 Andreas Jellinghaus + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +====================================================================== + +Portions contributed by Apple Inc. are subject to the following +license: + + Copyright 2004-2008 Apple Inc. All Rights Reserved. + + Export of this software from the United States of America may + require a specific license from the United States Government. + It is the responsibility of any person or organization + contemplating export to obtain such a license before exporting. + + WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + distribute this software and its documentation for any purpose and + without fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation, and that + the name of Apple Inc. not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. Apple Inc. makes no representations + about the suitability of this software for any purpose. It is + provided "as is" without express or implied warranty. + + THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +====================================================================== + +The implementations of UTF-8 string handling in src/util/support and +src/lib/krb5/unicode are subject to the following copyright and +permission notice: + + The OpenLDAP Public License + Version 2.8, 17 August 2003 + + Redistribution and use of this software and associated + documentation ("Software"), with or without modification, are + permitted provided that the following conditions are met: + + 1. Redistributions in source form must retain copyright statements + and notices, + + 2. Redistributions in binary form must reproduce applicable + copyright statements and notices, this list of conditions, and + the following disclaimer in the documentation and/or other + materials provided with the distribution, and + + 3. Redistributions must contain a verbatim copy of this document. + + The OpenLDAP Foundation may revise this license from time to time. + Each revision is distinguished by a version number. You may use + this Software under terms of this license revision or under the + terms of any subsequent revision of the license. + + THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS + CONTRIBUTORS "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE OPENLDAP FOUNDATION, ITS + CONTRIBUTORS, OR THE AUTHOR(S) OR OWNER(S) OF THE SOFTWARE BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + + The names of the authors and copyright holders must not be used in + advertising or otherwise to promote the sale, use or other dealing + in this Software without specific, written prior permission. Title + to copyright in this Software shall at all times remain with + copyright holders. + + OpenLDAP is a registered trademark of the OpenLDAP Foundation. + + Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, + California, USA. All Rights Reserved. Permission to copy and + distribute verbatim copies of this document is granted. + +Marked test programs in src/lib/krb5/krb have the following copyright: + + + Copyright (C) 2006 Kungliga Tekniska Högskolan + (Royal Institute of Technology, Stockholm, Sweden). + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. Neither the name of KTH nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +====================================================================== + +The KCM Mach RPC definition file used on macOS has the following +copyright: + + Copyright (C) 2009 Kungliga Tekniska Högskolan + (Royal Institute of Technology, Stockholm, Sweden). + All rights reserved. + + Portions Copyright (C) 2009 Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. Neither the name of the Institute nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +====================================================================== + +Portions of the RPC implementation in src/lib/rpc and +src/include/gssrpc have the following copyright and permission notice: + + Copyright (C) 2010, Oracle America, Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. Neither the name of the "Oracle America, Inc." nor the names of + its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +====================================================================== + + Copyright (C) 2006,2007,2009 NTT (Nippon Telegraph and Telephone + Corporation). All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer as + the first lines of this file unmodified. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + THIS SOFTWARE IS PROVIDED BY NTT "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +====================================================================== + + Copyright 2000 by Carnegie Mellon University + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appear in all + copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + Carnegie Mellon University not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. + + CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + +====================================================================== + + Copyright (C) 2002 Naval Research Laboratory (NRL/CCS) + + Permission to use, copy, modify and distribute this software and + its documentation is hereby granted, provided that both the + copyright notice and this permission notice appear in all copies of + the software, derivative works or modified versions, and any + portions thereof. + + NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER + RESULTING FROM THE USE OF THIS SOFTWARE. + +====================================================================== + +Portions extracted from Internet RFCs have the following copyright +notice: + + Copyright (C) The Internet Society (2006). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on + an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE + REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND + THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT + THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR + ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A + PARTICULAR PURPOSE. + +====================================================================== + + Copyright (C) 1991, 1992, 1994 by Cygnus Support. + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appear in all + copies and that both that copyright notice and this permission + notice appear in supporting documentation. Cygnus Support makes no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + +====================================================================== + + Copyright (C) 2006 Secure Endpoints Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +====================================================================== + +Portions of the implementation of the Fortuna-like PRNG are subject to +the following notice: + + + Copyright (C) 2005 Marko Kreen + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + Copyright (C) 1994 by the University of Southern California + + EXPORT OF THIS SOFTWARE from the United States of America may + require a specific license from the United States Government. It + is the responsibility of any person or organization + contemplating export to obtain such a license before exporting. + + WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute + this software and its documentation in source and binary forms is + hereby granted, provided that any documentation or other materials + related to such distribution or use acknowledge that the software + was developed by the University of Southern California. + + DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The + University of Southern California MAKES NO REPRESENTATIONS OR + WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not + limitation, the University of Southern California MAKES NO + REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY + PARTICULAR PURPOSE. The University of Southern California shall not + be held liable for any liability nor for any direct, indirect, or + consequential damages with respect to any claim by the user or + distributor of the ksu software. + +====================================================================== + + Copyright (C) 1995 + The President and Fellows of Harvard University + + This code is derived from software contributed to Harvard by Jeremy + Rassen. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgement: + + This product includes software developed by the University of + California, Berkeley and its contributors. + + 4. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +====================================================================== + + Copyright (C) 2008 by the Massachusetts Institute of Technology. + Copyright 1995 by Richard P. Basch. All Rights Reserved. + Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. + + Export of this software from the United States of America may + require a specific license from the United States Government. It + is the responsibility of any person or organization + contemplating export to obtain such a license before exporting. + + WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + distribute this software and its documentation for any purpose and + without fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation, and that + the name of Richard P. Basch, Lehman Brothers and M.I.T. not be + used in advertising or publicity pertaining to distribution of the + software without specific, written prior permission. Richard P. + Basch, Lehman Brothers and M.I.T. make no representations about the + suitability of this software for any purpose. It is provided "as + is" without express or implied warranty. + +====================================================================== + +The following notice applies to "src/lib/krb5/krb/strptime.c" and +"src/include/k5-queue.h". + + Copyright (C) 1997, 1998 The NetBSD Foundation, Inc. + All rights reserved. + + This code was contributed to The NetBSD Foundation by Klaus Klein. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgement: + + This product includes software developed by the NetBSD + Foundation, Inc. and its contributors. + + 4. Neither the name of The NetBSD Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +====================================================================== + +The following notice applies to Unicode library files in +"src/lib/krb5/unicode": + + Copyright 1997, 1998, 1999 Computing Research Labs, + New Mexico State University + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE COMPUTING RESEARCH LAB OR + NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +====================================================================== + +The following notice applies to "src/util/support/strlcpy.c": + + Copyright (C) 1998 Todd C. Miller "Todd.Miller@courtesan.com" + + Permission to use, copy, modify, and distribute this software for + any purpose with or without fee is hereby granted, provided that + the above copyright notice and this permission notice appear in all + copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +====================================================================== + +The following notice applies to "src/util/profile/argv_parse.c" and +"src/util/profile/argv_parse.h": + + Copyright 1999 by Theodore Ts'o. + + Permission to use, copy, modify, and distribute this software for + any purpose with or without fee is hereby granted, provided that + the above copyright notice and this permission notice appear in all + copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE + AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't + it sick that the U.S. culture of lawsuit-happy lawyers requires + this kind of disclaimer?) + +====================================================================== + +The following notice applies to SWIG-generated code in +"src/util/profile/profile_tcl.c": + + Copyright (C) 1999-2000, The University of Chicago + + This file may be freely redistributed without license or fee + provided this copyright message remains intact. + +====================================================================== + +The following notice applies to portiions of "src/lib/rpc" and +"src/include/gssrpc": + + Copyright (C) 2000 The Regents of the University of Michigan. All + rights reserved. + + Copyright (C) 2000 Dug Song "dugsong@UMICH.EDU". All rights + reserved, all wrongs reversed. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +Implementations of the MD4 algorithm are subject to the following +notice: + + Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD4 Message Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD4 Message Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + +====================================================================== + +Implementations of the MD5 algorithm are subject to the following +notice: + + Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message- Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + +====================================================================== + +The following notice applies to +"src/lib/crypto/crypto_tests/t_mddriver.c": + + Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All + rights reserved. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" without + express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + +====================================================================== + +Portions of "src/lib/krb5" are subject to the following notice: + + Copyright (C) 1994 CyberSAFE Corporation. + Copyright 1990,1991,2007,2008 by the Massachusetts Institute of +Technology. + All Rights Reserved. + + Export of this software from the United States of America may + require a specific license from the United States Government. It + is the responsibility of any person or organization + contemplating export to obtain such a license before exporting. + + WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + distribute this software and its documentation for any purpose and + without fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation, and that + the name of M.I.T. not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. Furthermore if you modify this software + you must label your software as modified software and not + distribute it in such a fashion that it might be confused with the + original M.I.T. software. Neither M.I.T., the Open Computing + Security Group, nor CyberSAFE Corporation make any representations + about the suitability of this software for any purpose. It is + provided "as is" without express or implied warranty. + +====================================================================== + +Portions contributed by PADL Software are subject to the following +license: + + Copyright (c) 2011, PADL Software Pty Ltd. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. Neither the name of PADL Software nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +====================================================================== + +The bundled libev source code is subject to the following license: + + All files in libev are Copyright (C)2007,2008,2009 Marc Alexander + Lehmann. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + + Alternatively, the contents of this package may be used under the + terms of the GNU General Public License ("GPL") version 2 or any + later version, in which case the provisions of the GPL are + applicable instead of the above. If you wish to allow the use of + your version of this package only under the terms of the GPL and + not to allow others to use your version of this file under the BSD + license, indicate your decision by deleting the provisions above + and replace them with the notice and other provisions required by + the GPL in this and the other files of this package. If you do not + delete the provisions above, a recipient may use your version of + this file under either the BSD or the GPL. + +====================================================================== + +Files copied from the Intel AESNI Sample Library are subject to the +following license: + + Copyright (C) 2010, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +====================================================================== + +The following notice applies to +"src/ccapi/common/win/OldCC/autolock.hxx": + + Copyright (C) 1998 by Danilo Almeida. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + + ====================================================================== + ====================================================================== + +LibFIDO + +Copyright (c) 2018-2021 Yubico AB. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +4th Party +========= + +libcbor +------- + +MIT License + +Copyright (c) 2014-2017 Pavel Kalvoda + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------ +---- +zlib +---- + +Copyright notice: + + (C) 1995-2017 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but +without warranty of any kind. The library has been entirely written by +Jean-loup Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. + +------------------------------------------------------------------------------ +OpenSSL (See its own license section) +------------------------------------------------------------------------------ + + ====================================================================== + ====================================================================== + +LZ4 + +LZ4 Library +Copyright (c) 2011-2016, Yann Collet +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ====================================================================== + ====================================================================== + +OpenSSL 3.0 + +You may be receiving a copy of OpenSSL 3.0 as part of this product in +object code form. +The terms of the Oracle license do NOT apply to OpenSSL 3.0. +OpenSSL 3.0 is licensed under the Apache 2.0 license, separate from +the Oracle product. +If you do not wish to install this library, you may remove it, but +the Oracle program might not operate properly or at all without it. + +/* + * Copyright 2003-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html +*/ + +See Apache License v2.0, January 2004 in the +'Standard Licenses' section. + + ====================================================================== + ====================================================================== + +OpenTelemetry C++ + +You may be receiving a copy of the opentelemetry-cpp library with +this MySQL product. The terms of the Oracle license do NOT apply +to the opentelemetry-cpp library; it is licensed under the following +license, separately from the Oracle programs you receive. +If you do not wish to install this program, you may delete its files +but the Oracle program might not operate properly or at all without it. + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +LICENSE: + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ +A copy of the Apache License v2.0, January 2004 license can be found +in the 'Standard Licenses' section. + + +4th party code included +======================= +exporters/etw +------------- +TraceLogging Dynamic for Windows + +Copyright (c) Microsoft Corporation. All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + +4th Party Libraries +=================== +opentelemetry-proto +------------------- +// Copyright 2019, OpenTelemetry Authors +// Copyright 2020, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +Apache License Text as listed above + +------------------------------------------------------------------------------ +protobuf +-------- + +Copyright 2008 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. + +------------------------------------------------------------------------------ +json (nlohmann) +---- +MIT License + +Copyright (c) 2013-2022 Niels Lohmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------ + + +curl +---- +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1996 - 2023, Daniel Stenberg, , and many +contributors, see the THANKS file. + +All rights reserved. + +Permission to use, copy, modify, and distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright +notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization of the copyright holder. + + ====================================================================== + ====================================================================== + +RapidJSON v1.1.0 + +Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All +rights reserved. + +If you have downloaded a copy of the RapidJSON binary from Tencent, please +note that the RapidJSON binary is licensed under the MIT License. +If you have downloaded a copy of the RapidJSON source code from Tencent, +please note that RapidJSON source code is licensed under the MIT License, +except for the third-party components listed below which are subject to +different license terms. Your integration of RapidJSON into your own +projects may require compliance with the MIT License, as well as the other +licenses applicable to the third-party components included within RapidJSON. +To avoid the problematic JSON license in your own projects, it's sufficient +to exclude the bin/jsonchecker/ directory, as it's the only code under the +JSON license. +A copy of the MIT License is included in this file. + +Other dependencies and licenses: + +Open Source Software Licensed Under the BSD License: +-------------------------------------------------------------------- + +The msinttypes r29 +Copyright (c) 2006-2013 Alexander Chemeris +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +* Neither the name of copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Open Source Software Licensed Under the JSON License: +-------------------------------------------------------------------- + +json.org +Copyright (c) 2002 JSON.org +All Rights Reserved. + +JSON_checker +Copyright (c) 2002 JSON.org +All Rights Reserved. + + +Terms of the JSON License: +--------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +Terms of the MIT License: +-------------------------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + ====================================================================== + ====================================================================== + +zlib + +Oracle gratefully acknowledges the contributions of Jean-loup Gailly +and Mark Adler in creating the zlib general purpose compression +library which is used in this product. + +Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. + + ====================================================================== + ====================================================================== + +ZSTD (Zstandard) + +Zstandard is dual-licensed under [BSD](LICENSE) and [GPLv2](COPYING). + + /* + * This source code is licensed under both the BSD-style license (found in + * the LICENSE file in the root directory of this source tree) and the GPLv2 + * (found in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +Oracle elects the BSD license + +LICENSE: +Copyright (c) 2016-present, Facebook, Inc. All rights reserved. +Copyright (C) 2012-2016, Yann Collet. +Copyright (c) 2003-2008 Yuta Mori All Rights Reserved. +Copyright (c) 2016 Tino Reichardt +Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc. +Copyright (c) 2016-present, Yann Collet, Facebook, Inc. +Copyright (c) 2018-present, Facebook, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The following is from the COPYING file and is included for completeness: +------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + + ====================================================================== + ====================================================================== + +Standard Licenses + +Apache License v2.0, January 2004 + +The following applies to all products licensed under the Apache 2.0 +License: You may not use the identified files except in compliance +with the Apache License, Version 2.0 (the "License.") You may obtain a +copy of the License at http://www.apache.org/licenses/LICENSE-2.0. A +copy of the license is also reproduced below. Unless required by +applicable law or agreed to in writing, software distributed under the +License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for +the specific language governing permissions and limitations under the +License. + +Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the +copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other +entities that control, are controlled by, or are under common control +with that entity. For the purposes of this definition, "control" means +(i) the power, direct or indirect, to cause the direction or +management of such entity, whether by contract or otherwise, or (ii) +ownership of fifty percent (50%) or more of the outstanding shares, or +(iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation +source, and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but not +limited to compiled object code, generated documentation, and +conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object +form, made available under the License, as indicated by a copyright +notice that is included in or attached to the work (an example is +provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object +form, that is based on (or derived from) the Work and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. For the +purposes of this License, Derivative Works shall not include works +that remain separable from, or merely link (or bind by name) to the +interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the +original version of the Work and any modifications or additions to +that Work or Derivative Works thereof, that is intentionally submitted +to Licensor for inclusion in the Work by the copyright owner or by an +individual or Legal Entity authorized to submit on behalf of the +copyright owner. For the purposes of this definition, "submitted" +means any form of electronic, verbal, or written communication sent to +the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control +systems, and issue tracking systems that are managed by, or on behalf +of, the Licensor for the purpose of discussing and improving the Work, +but excluding communication that is conspicuously marked or otherwise +designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, publicly +display, publicly perform, sublicense, and distribute the Work and +such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except +as stated in this section) patent license to make, have made, use, +offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such +Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work to +which such Contribution(s) was submitted. If You institute patent +litigation against any entity (including a cross-claim or counterclaim +in a lawsuit) alleging that the Work or a Contribution incorporated +within the Work constitutes direct or contributory patent +infringement, then any patent licenses granted to You under this +License for that Work shall terminate as of the date such litigation +is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work +or Derivative Works thereof in any medium, with or without +modifications, and in Source or Object form, provided that You meet +the following conditions: + +(a) You must give any other recipients of the Work or Derivative Works +a copy of this License; and + +(b) You must cause any modified files to carry prominent notices +stating that You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works that +You distribute, all copyright, patent, trademark, and attribution +notices from the Source form of the Work, excluding those notices that +do not pertain to any part of the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its +distribution, then any Derivative Works that You distribute must +include a readable copy of the attribution notices contained + +within such NOTICE file, excluding those notices that do not pertain +to any part of the Derivative Works, in at least one of the following +places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided +along with the Derivative Works; or, within a display generated by the +Derivative Works, if and wherever such third-party notices normally +appear. The contents of the NOTICE file are for informational purposes +only and do not modify the License. You may add Your own attribution +notices within Derivative Works that You distribute, alongside or as +an addendum to the NOTICE text from the Work, provided that such +additional attribution notices cannot be construed as modifying the +License. + +You may add Your own copyright statement to Your modifications and may +provide additional or different license terms and conditions for use, +reproduction, or distribution of Your modifications, or for any such +Derivative Works as a whole, provided Your use, reproduction, and +distribution of the Work otherwise complies with the conditions stated +in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work by +You to the Licensor shall be under the terms and conditions of this +License, without any additional terms or conditions. Notwithstanding +the above, nothing herein shall supersede or modify the terms of any +separate license agreement you may have executed with Licensor +regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed +to in writing, Licensor provides the Work (and each Contributor +provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied, including, without +limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, +MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely +responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your +exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, unless +required by applicable law (such as deliberate and grossly negligent +acts) or agreed to in writing, shall any Contributor be liable to You +for damages, including any direct, indirect, special, incidental, or +consequential damages of any character arising as a result of this +License or out of the use or inability to use the Work (including but +not limited to damages for loss of goodwill, work stoppage, computer +failure or malfunction, or any and all other commercial damages or +losses), even if such Contributor has been advised of the possibility +of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, and +charge a fee for, acceptance of support, warranty, indemnity, or other +liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only on +Your own behalf and on Your sole responsibility, not on behalf of any +other Contributor, and only if You agree to indemnify, defend, and +hold each Contributor harmless for any liability incurred by, or +claims asserted against, such Contributor by reason of your accepting +any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included +on the same "printed page" as the copyright notice for easier identification +within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing permissions +and limitations under the License. + + ====================================================================== + ====================================================================== + +Written Offer for Source Code + + For any software that you receive from Oracle in binary form which is + licensed under an open source license that gives you the right to + receive the source code for that binary, you can obtain a copy of the + applicable source code by visiting + http://www.oracle.com/goto/opensourcecode. If the source code for the + binary was not provided to you with the binary, you can also receive a + copy of the source code on physical media by submitting a written + request to the address listed below or by sending an email to Oracle + using the following link: + http://www.oracle.com/goto/opensourcecode/request. + + Oracle America, Inc. + Attn: Senior Vice President + Development and Engineering Legal + 500 Oracle Parkway, 10th Floor + Redwood Shores, CA 94065 + + Your request should include: + + * The name of the binary for which you are requesting the source code + + * The name and version number of the Oracle product containing the + binary + + * The date you received the Oracle product + + * Your name + + * Your company name (if applicable) + + * Your return mailing address and email, and + + * A telephone number in the event we need to reach you. + + + We may charge you a fee to cover the cost of physical media and + processing. + + Your request must be sent + + a. within three (3) years of the date you received the Oracle product + that included the binary that is the subject of your request, or + + b. in the case of code licensed under the GPL v3 for as long as Oracle + offers spare parts or customer support for that product model. diff --git a/Libraries/mysql-connector/README.txt b/Libraries/mysql-connector/README.txt new file mode 100644 index 0000000..ffdc35c --- /dev/null +++ b/Libraries/mysql-connector/README.txt @@ -0,0 +1,39 @@ +Copyright (c) 2008, 2024, Oracle and/or its affiliates. + +This is a release of MySQL Connector/C++, the C++ interface for communicating +with MySQL servers. + +License information can be found in the LICENSE.txt file. + +This distribution may include materials developed by third parties. +For license and attribution notices for these materials, please refer to the LICENSE.txt file. + +For more information on MySQL Connector/C++, visit + https://dev.mysql.com/doc/connector-cpp/en/ + +For additional downloads and the source of MySQL Connector/C++, visit + http://dev.mysql.com/downloads + +MySQL Connector/C++ is brought to you by the MySQL team at Oracle. + + +DOCUMENTATION LOCATION +====================== + +You can find the documentation on the MySQL website at + + +For the new features/bugfix history, see release notes at +. +Note that the initial releases used major version 2.0. + +CONTACT +======= + +For general discussion of the MySQL Connector/C++ please use the C/C++ +community forum at or join +the MySQL Connector/C++ mailing list at . + +Bugs can be reported at . Please +use the "Connector / C++" or "Connector / C++ Documentation" bug +category. diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/build_config.h b/Libraries/mysql-connector/include/jdbc/cppconn/build_config.h new file mode 100644 index 0000000..449d38a --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/build_config.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_BUILD_CONFIG_H_ +#define _SQL_BUILD_CONFIG_H_ + +#ifdef STATIC_CONCPP + #define CPPCONN_PUBLIC_FUNC +#endif + + +#if defined _MSC_VER + + #define DLL_EXPORT __declspec(dllexport) + #define DLL_IMPORT __declspec(dllimport) + #define DLL_LOCAL + +#elif __GNUC__ >= 4 + + #define DLL_EXPORT __attribute__ ((visibility ("default"))) + #define DLL_IMPORT + #define DLL_LOCAL __attribute__ ((visibility ("hidden"))) + +#elif defined __SUNPRO_CC || defined __SUNPRO_C + + #define DLL_EXPORT __global + #define DLL_IMPORT __global + #define DLL_LOCAL __hidden + +#else + + #define DLL_EXPORT + #define DLL_IMPORT + #define DLL_LOCAL + +#endif + + +#ifndef CPPCONN_PUBLIC_FUNC + + #ifdef connector_jdbc_EXPORTS + #define CPPCONN_PUBLIC_FUNC DLL_EXPORT + #else + // this is for static build + #ifdef CPPCONN_LIB_BUILD + #define CPPCONN_PUBLIC_FUNC + #else + // this is for clients using dynamic lib + #define CPPCONN_PUBLIC_FUNC DLL_IMPORT + #endif + #endif + +#endif + + +#ifdef _MSC_VER + + /* + Warning 4251 is about non dll-interface classes being used by ones exported + from our DLL (for example std lib classes or Boost ones). Following + the crowd, we ignore this issue for now. + */ + + __pragma(warning (disable:4251)) + +#elif defined __SUNPRO_CC || defined __SUNPRO_C +#else + + /* + These are triggered by, e.g., std::auto_ptr<> which is used by Boost. + */ + + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +#endif + +#endif //#ifndef _SQL_BUILD_CONFIG_H_ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/callback.h b/Libraries/mysql-connector/include/jdbc/cppconn/callback.h new file mode 100644 index 0000000..af55532 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/callback.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_CALLBACK_H_ +#define _SQL_CALLBACK_H_ + +#include "sqlstring.h" +#include + +namespace sql +{ + +namespace mysql +{ +class MySQL_Connection; +class MySQL_Driver; +} + + +/* + A callback to be used with `Driver::setCallback()` to define reaction + to the user action request during WebAuthn authentication handshake. + + The client library defines default reaction which prints message on stderr. + This callback can be used to change it. + + Example usage: + + // Use lambda + + driver->setCallback(WebAuthn_Callback{[](SQLString msg){ + cerr << "User action request: " << msg << endl; + }}); + + // Disable default behavior (and do nothing upon action request) + + driver->setCallback(WebAuthn_Callback{}); + + // Return to default behavior + + driver->setCallbacak(WebAuthn_Callback{nullptr}); + + // User defined callback + + struct My_Callback : WebAuthn_Callback + { + void ActionRequested(SQLString) override; + } + cb; + + driver->setCallback(cb); +*/ + +class WebAuthn_Callback +{ + std::function callback_func; + +public: + + /* + Create a callback that will call given lambda upon user action request. + */ + + WebAuthn_Callback(std::function&& cb) + : callback_func{std::move(cb)} + {} + + /* + Create an empty callback that will do nothing upon user action request. + This disables the default callback defined by the client library. + */ + + WebAuthn_Callback() + : callback_func{[](SQLString){}} + {} + + /* + Create a null callback. Setting such callback has the effect of using + the default callback defined by the client library. + */ + + WebAuthn_Callback(std::nullptr_t) + {} + + /* + Derived class can override this method to react to user action request. + */ + + virtual void ActionRequested(sql::SQLString msg) + { + if (callback_func) + callback_func(msg); + } + + // Returns true if this callback is not null. + + operator bool() const + { + return (bool)callback_func; + } + + void operator()(sql::SQLString msg) + { + ActionRequested(msg); + } + +}; + + +/* + * TODO: This class is not needed. Remove it when the decision to + * break ABI is made. + * + * Class that provides functionality allowing user code to set the + * callback functions through inheriting, passing the callback as + * constructor parameters or using lambdas. + */ + +class Fido_Callback +{ + std::function callback_func = nullptr; + bool is_null = false; + +public: + + /** + * Constructor to set the callback as function or as lambda + */ + Fido_Callback(std::function cb) : callback_func(cb) + {} + + Fido_Callback() + {} + + /** + * Constructor to reset the callback to default + */ + Fido_Callback(std::nullptr_t) : is_null(true) + {} + + /** + * Override this message to receive Fido Action Requests + */ + virtual void FidoActionRequested(sql::SQLString msg) + { + if (callback_func) + callback_func(msg); + } + + operator bool() const + { + return !is_null; + } + + void operator()(sql::SQLString msg) + { + if (is_null) + return; + FidoActionRequested(msg); + } + + friend class mysql::MySQL_Connection; + friend class mysql::MySQL_Driver; +}; + + +} /* namespace sql */ + +#endif // _SQL_CONNECTION_H_ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/config.h b/Libraries/mysql-connector/include/jdbc/cppconn/config.h new file mode 100644 index 0000000..a29a218 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/config.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// libmysql defines HAVE_STRTOUL (on win), so we have to follow different pattern in definitions names +// to avoid annoying warnings. + +#define HAVE_FUNCTION_STRTOLD 1 +#define HAVE_FUNCTION_STRTOLL 1 +#define HAVE_FUNCTION_STRTOL 1 +#define HAVE_FUNCTION_STRTOULL 1 + +#define HAVE_FUNCTION_STRTOUL 1 + +#define HAVE_FUNCTION_STRTOIMAX 1 +#define HAVE_FUNCTION_STRTOUMAX 1 + +#define HAVE_STDINT_H 1 +#define HAVE_INTTYPES_H 1 + +#define HAVE_INT8_T 1 +#define HAVE_UINT8_T 1 +#define HAVE_INT16_T 1 +#define HAVE_UINT16_T 1 +#define HAVE_INT32_T 1 +#define HAVE_UINT32_T 1 +#define HAVE_INT32_T 1 +#define HAVE_UINT32_T 1 +#define HAVE_INT64_T 1 +#define HAVE_UINT64_T 1 +#define HAVE_MS_INT8 1 +#define HAVE_MS_UINT8 1 +#define HAVE_MS_INT16 1 +#define HAVE_MS_UINT16 1 +#define HAVE_MS_INT32 1 +#define HAVE_MS_UINT32 1 +#define HAVE_MS_INT64 1 +#define HAVE_MS_UINT64 1 + + +#ifdef HAVE_STDINT_H +#include +#endif + + +#if defined(HAVE_INTTYPES_H) && !defined(_WIN32) +#include +#endif + +#if defined(_WIN32) +#ifndef CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES + +#if _MSC_VER >= 1600 + +#include + +#else + +#if !defined(HAVE_INT8_T) && defined(HAVE_MS_INT8) +typedef __int8 int8_t; +#endif + +#ifdef HAVE_MS_UINT8 +typedef unsigned __int8 uint8_t; +#endif +#ifdef HAVE_MS_INT16 +typedef __int16 int16_t; +#endif + +#ifdef HAVE_MS_UINT16 +typedef unsigned __int16 uint16_t; +#endif + +#ifdef HAVE_MS_INT32 +typedef __int32 int32_t; +#endif + +#ifdef HAVE_MS_UINT32 +typedef unsigned __int32 uint32_t; +#endif + +#ifdef HAVE_MS_INT64 +typedef __int64 int64_t; +#endif +#ifdef HAVE_MS_UINT64 +typedef unsigned __int64 uint64_t; +#endif + +#endif // _MSC_VER >= 1600 +#endif // CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES +#endif // _WIN32 diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/connection.h b/Libraries/mysql-connector/include/jdbc/cppconn/connection.h new file mode 100644 index 0000000..b33f3ce --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/connection.h @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_CONNECTION_H_ +#define _SQL_CONNECTION_H_ + +#include + +#include "build_config.h" +#include "warning.h" +#include "sqlstring.h" +#include "variant.h" + +/* + Options used on ConnectOptionsMap +*/ + +/* + Connect related +*/ +#define OPT_HOSTNAME "hostName" +#define OPT_USERNAME "userName" +#define OPT_PASSWORD "password" +#define OPT_PASSWORD1 "password1" +#define OPT_PASSWORD2 "password2" +#define OPT_PASSWORD3 "password3" +#define OPT_PORT "port" +#define OPT_SOCKET "socket" +#define OPT_PIPE "pipe" +#define OPT_SCHEMA "schema" +#define OPT_MULTI_HOST "OPT_MULTI_HOST" +#define OPT_DNS_SRV "OPT_DNS_SRV" +#define OPT_NAMED_PIPE "OPT_NAMED_PIPE" +#define OPT_INIT_COMMAND "preInit" +#define OPT_POST_INIT_COMMAND "postInit" +#define OPT_LOCAL_INFILE "OPT_LOCAL_INFILE" +#define OPT_LOAD_DATA_LOCAL_DIR "OPT_LOAD_DATA_LOCAL_DIR" + +/* + SSL related +*/ +#define OPT_SSL_MODE "ssl-mode" +#define OPT_SSL_KEY "ssl-key" +#define OPT_SSL_CERT "ssl-cert" +#define OPT_SSL_CA "ssl-ca" +#define OPT_SSL_CAPATH "ssl-capath" +#define OPT_SSL_CIPHER "ssl-cipher" +#define OPT_SSL_CRL "ssl-crl" +#define OPT_SSL_CRLPATH "ssl-crlpath" +#define OPT_SERVER_PUBLIC_KEY "rsaKey" +#define OPT_TLS_VERSION "tls-version" + +/* + Connection related +*/ +#define OPT_RECONNECT "OPT_RECONNECT" +#define OPT_RETRY_COUNT "OPT_RETRY_COUNT" +#define OPT_CONNECT_TIMEOUT "OPT_CONNECT_TIMEOUT" +#define OPT_READ_TIMEOUT "OPT_READ_TIMEOUT" +#define OPT_WRITE_TIMEOUT "OPT_WRITE_TIMEOUT" +#define OPT_MAX_ALLOWED_PACKET "OPT_MAX_ALLOWED_PACKET" +#define OPT_NET_BUFFER_LENGTH "OPT_NET_BUFFER_LENGTH" + +/* + Connection Attributes +*/ +#define OPT_CONNECT_ATTR_ADD "OPT_CONNECT_ATTR_ADD" +#define OPT_CONNECT_ATTR_DELETE "OPT_CONNECT_ATTR_DELETE" +#define OPT_CONNECT_ATTR_RESET "OPT_CONNECT_ATTR_RESET" + +/* + Authentication +*/ +#define OPT_ENABLE_CLEARTEXT_PLUGIN "OPT_ENABLE_CLEARTEXT_PLUGIN" +#define OPT_CAN_HANDLE_EXPIRED_PASSWORDS "OPT_CAN_HANDLE_EXPIRED_PASSWORDS" +#define OPT_GET_SERVER_PUBLIC_KEY "OPT_GET_SERVER_PUBLIC_KEY" +#define OPT_LEGACY_AUTH "useLegacyAuth" +#define OPT_DEFAULT_AUTH "defaultAuth" + +/* + Charracter set results and Metadata +*/ +#define OPT_CHARACTER_SET_RESULTS "characterSetResults" +#define OPT_OPTIONAL_RESULTSET_METADATA "OPT_OPTIONAL_RESULTSET_METADATA" +#define OPT_REPORT_DATA_TRUNCATION "OPT_REPORT_DATA_TRUNCATION" +#define OPT_CHARSET_NAME "OPT_CHARSET_NAME" +#define OPT_DEFAULT_STMT_RESULT_TYPE "defaultStatementResultType" + +/* + Client side options + */ +#define OPT_CLIENT_COMPRESS "CLIENT_COMPRESS" +#define OPT_CLIENT_FOUND_ROWS "CLIENT_FOUND_ROWS" +#define OPT_CLIENT_IGNORE_SIGPIPE "CLIENT_IGNORE_SIGPIPE" +#define OPT_CLIENT_IGNORE_SPACE "CLIENT_IGNORE_SPACE" +#define OPT_CLIENT_INTERACTIVE "CLIENT_INTERACTIVE" +#define OPT_CLIENT_LOCAL_FILES "CLIENT_LOCAL_FILES" +#define OPT_CLIENT_MULTI_STATEMENTS "CLIENT_MULTI_STATEMENTS" +#define OPT_CLIENT_NO_SCHEMA "CLIENT_NO_SCHEMA" +#define OPT_SET_CHARSET_DIR "charsetDir" +#define OPT_PLUGIN_DIR "pluginDir" +#define OPT_READ_DEFAULT_GROUP "readDefaultGroup" +#define OPT_READ_DEFAULT_FILE "readDefaultFile" + +/* + Auth plugin options +*/ +#define OPT_OCI_CONFIG_FILE "OPT_OCI_CONFIG_FILE" +#define OPT_AUTHENTICATION_KERBEROS_CLIENT_MODE \ + "OPT_AUTHENTICATION_KERBEROS_CLIENT_MODE" +#define OPT_OCI_CLIENT_CONFIG_PROFILE "OPT_OCI_CLIENT_CONFIG_PROFILE" + +/* + Telemetry options +*/ +#define OPT_OPENTELEMETRY "OPT_OPENTELEMETRY" + +namespace sql +{ + +typedef sql::Variant ConnectPropertyVal; + +typedef std::map< sql::SQLString, ConnectPropertyVal > ConnectOptionsMap; + +class DatabaseMetaData; +class PreparedStatement; +class Statement; +class Driver; + +typedef enum transaction_isolation +{ + TRANSACTION_NONE= 0, + TRANSACTION_READ_COMMITTED, + TRANSACTION_READ_UNCOMMITTED, + TRANSACTION_REPEATABLE_READ, + TRANSACTION_SERIALIZABLE +} enum_transaction_isolation; + +enum ssl_mode +{ + SSL_MODE_DISABLED= 1, SSL_MODE_PREFERRED, SSL_MODE_REQUIRED, + SSL_MODE_VERIFY_CA, SSL_MODE_VERIFY_IDENTITY +}; + +typedef enum opentelemetry_mode +{ + OTEL_DISABLED = 1, OTEL_PREFERRED, OTEL_REQUIRED +} enum_opentelemetry_mode; + +class CPPCONN_PUBLIC_FUNC Savepoint +{ + /* Prevent use of these */ + Savepoint(const Savepoint &); + void operator=(Savepoint &); +public: + Savepoint() {}; + virtual ~Savepoint() {}; + virtual int getSavepointId() = 0; + + virtual sql::SQLString getSavepointName() = 0; +}; + + +class CPPCONN_PUBLIC_FUNC Connection +{ + /* Prevent use of these */ + Connection(const Connection &); + void operator=(Connection &); +public: + + Connection() {}; + + virtual ~Connection() {}; + + virtual void clearWarnings() = 0; + + virtual Statement *createStatement() = 0; + + virtual void close() = 0; + + virtual void commit() = 0; + + virtual bool getAutoCommit() = 0; + + virtual sql::SQLString getCatalog() = 0; + + virtual Driver *getDriver() = 0; + + virtual sql::SQLString getSchema() = 0; + + virtual sql::SQLString getClientInfo() = 0; + + virtual void getClientOption(const sql::SQLString & optionName, void * optionValue) = 0; + + virtual sql::SQLString getClientOption(const sql::SQLString & optionName) = 0; + + virtual DatabaseMetaData * getMetaData() = 0; + + virtual enum_transaction_isolation getTransactionIsolation() = 0; + + virtual const SQLWarning * getWarnings() = 0; + + virtual bool isClosed() = 0; + + virtual bool isReadOnly() = 0; + + virtual bool isValid() = 0; + + virtual bool reconnect() = 0; + + virtual sql::SQLString nativeSQL(const sql::SQLString& sql) = 0; + + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql) = 0; + + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys) = 0; + + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int* columnIndexes) = 0; + + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency) = 0; + + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) = 0; + + virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]) = 0; + + virtual void releaseSavepoint(Savepoint * savepoint) = 0; + + virtual void rollback() = 0; + + virtual void rollback(Savepoint * savepoint) = 0; + + virtual void setAutoCommit(bool autoCommit) = 0; + + virtual void setCatalog(const sql::SQLString& catalog) = 0; + + virtual void setSchema(const sql::SQLString& catalog) = 0; + + virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue) = 0; + + virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue) = 0; + + virtual void setHoldability(int holdability) = 0; + + virtual void setReadOnly(bool readOnly) = 0; + + virtual Savepoint * setSavepoint() = 0; + + virtual Savepoint * setSavepoint(const sql::SQLString& name) = 0; + + virtual void setTransactionIsolation(enum_transaction_isolation level) = 0; + + /* virtual void setTypeMap(Map map) = 0; */ +}; + +} /* namespace sql */ + +#endif // _SQL_CONNECTION_H_ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/datatype.h b/Libraries/mysql-connector/include/jdbc/cppconn/datatype.h new file mode 100644 index 0000000..f0aeff0 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/datatype.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_DATATYPE_H_ +#define _SQL_DATATYPE_H_ + +namespace sql +{ + +class DataType +{ + DataType(); +public: + enum { + UNKNOWN = 0, + BIT, + TINYINT, + SMALLINT, + MEDIUMINT, + INTEGER, + BIGINT, + REAL, + DOUBLE, + DECIMAL, + NUMERIC, + CHAR, + BINARY, + VARCHAR, + VARBINARY, + LONGVARCHAR, + LONGVARBINARY, + TIMESTAMP, + DATE, + TIME, + YEAR, + GEOMETRY, + ENUM, + SET, + SQLNULL, + JSON, + VECTOR + }; +}; + +} /* namespace */ + +#endif /* _SQL_DATATYPE_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/driver.h b/Libraries/mysql-connector/include/jdbc/cppconn/driver.h new file mode 100644 index 0000000..44e3875 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/driver.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_DRIVER_H_ +#define _SQL_DRIVER_H_ + +#include "connection.h" +#include "build_config.h" +#include "callback.h" + +namespace sql +{ + +class CPPCONN_PUBLIC_FUNC Driver +{ +protected: + virtual ~Driver() {} +public: + // Attempts to make a database connection to the given URL. + + virtual Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) = 0; + + virtual Connection * connect(ConnectOptionsMap & options) = 0; + + virtual int getMajorVersion() = 0; + + virtual int getMinorVersion() = 0; + + virtual int getPatchVersion() = 0; + + virtual const sql::SQLString & getName() = 0; + + // TODO: Remove these functions when ABI breaking change is made elsewhere. + virtual void setCallBack(sql::Fido_Callback &cb) = 0; + virtual void setCallBack(sql::Fido_Callback &&cb) = 0; + + virtual void threadInit() = 0; + + virtual void threadEnd() = 0; + + virtual void setCallBack(sql::WebAuthn_Callback &cb) = 0; + virtual void setCallBack(sql::WebAuthn_Callback &&cb) = 0; +}; + +} /* namespace sql */ + + +CPPCONN_PUBLIC_FUNC void check(const std::string &); +CPPCONN_PUBLIC_FUNC void check(const std::map &); + +/* + Checks if user standard lib is compatible with connector one +*/ +inline static void check_lib() +{ + check(std::string{}); + check(std::map{}); +} + +extern "C" +{ + + CPPCONN_PUBLIC_FUNC sql::Driver * _get_driver_instance_by_name(const char * const clientlib); + + /* If dynamic loading is disabled in a driver then this function works just like get_driver_instance() */ + inline static sql::Driver * get_driver_instance_by_name(const char * const clientlib) + { + check_lib(); + return _get_driver_instance_by_name(clientlib); + } + + inline static sql::Driver * get_driver_instance() + { + return get_driver_instance_by_name(""); + } +} + +#endif /* _SQL_DRIVER_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/exception.h b/Libraries/mysql-connector/include/jdbc/cppconn/exception.h new file mode 100644 index 0000000..9f43fa7 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/exception.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_EXCEPTION_H_ +#define _SQL_EXCEPTION_H_ + +#include "build_config.h" +#include +#include +#include + +namespace sql +{ + +#define MEMORY_ALLOC_OPERATORS(Class) \ + void* operator new(size_t size){ return ::operator new(size); } \ + void* operator new(size_t, void*) noexcept; \ + void* operator new(size_t, const std::nothrow_t&) noexcept; \ + void* operator new[](size_t); \ + void* operator new[](size_t, void*) noexcept; \ + void* operator new[](size_t, const std::nothrow_t&) noexcept; \ + void* operator new(size_t N, std::allocator&); + + +class SQLException : public std::runtime_error +{ +protected: + const std::string sql_state; + const int errNo; + +public: + SQLException(const SQLException& e) : std::runtime_error(e.what()), sql_state(e.sql_state), errNo(e.errNo) {} + + SQLException(const std::string& reason, const std::string& SQLState, int vendorCode) : + std::runtime_error (reason ), + sql_state (SQLState ), + errNo (vendorCode) + {} + + SQLException(const std::string& reason, const std::string& SQLState) : std::runtime_error(reason), sql_state(SQLState), errNo(0) {} + + SQLException(const std::string& reason) : std::runtime_error(reason), sql_state("HY000"), errNo(0) {} + + SQLException() : std::runtime_error(""), sql_state("HY000"), errNo(0) {} + + const std::string & getSQLState() const + { + return sql_state; + } + + const char * getSQLStateCStr() const + { + return sql_state.c_str(); + } + + + int getErrorCode() const + { + return errNo; + } + + virtual ~SQLException() noexcept {}; + +protected: + MEMORY_ALLOC_OPERATORS(SQLException) +}; + +struct MethodNotImplementedException : public SQLException +{ + MethodNotImplementedException(const MethodNotImplementedException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } + MethodNotImplementedException(const std::string& reason) : SQLException(reason, "", 0) {} +}; + +struct InvalidArgumentException : public SQLException +{ + InvalidArgumentException(const InvalidArgumentException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } + InvalidArgumentException(const std::string& reason) : SQLException(reason, "", 0) {} +}; + +struct InvalidInstanceException : public SQLException +{ + InvalidInstanceException(const InvalidInstanceException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } + InvalidInstanceException(const std::string& reason) : SQLException(reason, "", 0) {} +}; + + +struct NonScrollableException : public SQLException +{ + NonScrollableException(const NonScrollableException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } + NonScrollableException(const std::string& reason) : SQLException(reason, "", 0) {} +}; + +struct SQLUnsupportedOptionException : public SQLException +{ + SQLUnsupportedOptionException(const SQLUnsupportedOptionException& e, const std::string conn_option) : + SQLException(e.what(), e.sql_state, e.errNo), + option(conn_option ) + {} + + SQLUnsupportedOptionException(const std::string& reason, const std::string conn_option) : + SQLException(reason, "", 0), + option(conn_option ) + {} + + const char *getConnectionOption() const + { + return option.c_str(); + } + + ~SQLUnsupportedOptionException() noexcept {}; +protected: + const std::string option; +}; + + +} /* namespace sql */ + +#endif /* _SQL_EXCEPTION_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/metadata.h b/Libraries/mysql-connector/include/jdbc/cppconn/metadata.h new file mode 100644 index 0000000..b5b6d66 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/metadata.h @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_METADATA_H_ +#define _SQL_METADATA_H_ + +#include +#include +#include "datatype.h" +#include "sqlstring.h" + +namespace sql +{ +class ResultSet; +class Connection; + +class DatabaseMetaData +{ +protected: + virtual ~DatabaseMetaData() {} + +public: + enum + { + attributeNoNulls = 0, + attributeNullable, + attributeNullableUnknown + }; + enum + { + bestRowTemporary = 0, + bestRowTransaction, + bestRowSession + }; + enum + { + bestRowUnknown = 0, + bestRowNotPseudo, + bestRowPseudo + }; + enum + { + columnNoNulls = 0, + columnNullable, + columnNullableUnknown + }; + enum + { + importedKeyCascade = 0, + importedKeyInitiallyDeferred, + importedKeyInitiallyImmediate, + importedKeyNoAction, + importedKeyNotDeferrable, + importedKeyRestrict, + importedKeySetDefault, + importedKeySetNull + }; + enum + { + procedureColumnIn = 0, + procedureColumnInOut, + procedureColumnOut, + procedureColumnResult, + procedureColumnReturn, + procedureColumnUnknown, + procedureNoNulls, + procedureNoResult, + procedureNullable, + procedureNullableUnknown, + procedureResultUnknown, + procedureReturnsResult + }; + enum + { + sqlStateSQL99 = 0, + sqlStateXOpen + }; + enum + { + tableIndexClustered = 0, + tableIndexHashed, + tableIndexOther, + tableIndexStatistic + }; + enum + { + versionColumnUnknown = 0, + versionColumnNotPseudo = 1, + versionColumnPseudo = 2 + }; + enum + { + typeNoNulls = 0, + typeNullable = 1, + typeNullableUnknown = 2 + }; + enum + { + typePredNone = 0, + typePredChar = 1, + typePredBasic= 2, + typeSearchable = 3 + }; + + + virtual bool allProceduresAreCallable() = 0; + + virtual bool allTablesAreSelectable() = 0; + + virtual bool dataDefinitionCausesTransactionCommit() = 0; + + virtual bool dataDefinitionIgnoredInTransactions() = 0; + + virtual bool deletesAreDetected(int type) = 0; + + virtual bool doesMaxRowSizeIncludeBlobs() = 0; + + virtual ResultSet * getAttributes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, const sql::SQLString& attributeNamePattern) = 0; + + virtual ResultSet * getBestRowIdentifier(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, int scope, bool nullable) = 0; + + virtual ResultSet * getCatalogs() = 0; + + virtual const sql::SQLString& getCatalogSeparator() = 0; + + virtual const sql::SQLString& getCatalogTerm() = 0; + + virtual ResultSet * getColumnPrivileges(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, const sql::SQLString& columnNamePattern) = 0; + + virtual ResultSet * getColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, const sql::SQLString& columnNamePattern) = 0; + + virtual Connection * getConnection() = 0; + + virtual ResultSet * getCrossReference(const sql::SQLString& primaryCatalog, const sql::SQLString& primarySchema, const sql::SQLString& primaryTable, const sql::SQLString& foreignCatalog, const sql::SQLString& foreignSchema, const sql::SQLString& foreignTable) = 0; + + virtual unsigned int getDatabaseMajorVersion() = 0; + + virtual unsigned int getDatabaseMinorVersion() = 0; + + virtual unsigned int getDatabasePatchVersion() = 0; + + virtual const sql::SQLString& getDatabaseProductName() = 0; + + virtual SQLString getDatabaseProductVersion() = 0; + + virtual int getDefaultTransactionIsolation() = 0; + + virtual unsigned int getDriverMajorVersion() = 0; + + virtual unsigned int getDriverMinorVersion() = 0; + + virtual unsigned int getDriverPatchVersion() = 0; + + virtual const sql::SQLString& getDriverName() = 0; + + virtual const sql::SQLString& getDriverVersion() = 0; + + virtual ResultSet * getExportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; + + virtual const sql::SQLString& getExtraNameCharacters() = 0; + + virtual const sql::SQLString& getIdentifierQuoteString() = 0; + + virtual ResultSet * getImportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; + + virtual ResultSet * getIndexInfo(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, bool unique, bool approximate) = 0; + + virtual unsigned int getCDBCMajorVersion() = 0; + + virtual unsigned int getCDBCMinorVersion() = 0; + + virtual unsigned int getMaxBinaryLiteralLength() = 0; + + virtual unsigned int getMaxCatalogNameLength() = 0; + + virtual unsigned int getMaxCharLiteralLength() = 0; + + virtual unsigned int getMaxColumnNameLength() = 0; + + virtual unsigned int getMaxColumnsInGroupBy() = 0; + + virtual unsigned int getMaxColumnsInIndex() = 0; + + virtual unsigned int getMaxColumnsInOrderBy() = 0; + + virtual unsigned int getMaxColumnsInSelect() = 0; + + virtual unsigned int getMaxColumnsInTable() = 0; + + virtual unsigned int getMaxConnections() = 0; + + virtual unsigned int getMaxCursorNameLength() = 0; + + virtual unsigned int getMaxIndexLength() = 0; + + virtual unsigned int getMaxProcedureNameLength() = 0; + + virtual unsigned int getMaxRowSize() = 0; + + virtual unsigned int getMaxSchemaNameLength() = 0; + + virtual unsigned int getMaxStatementLength() = 0; + + virtual unsigned int getMaxStatements() = 0; + + virtual unsigned int getMaxTableNameLength() = 0; + + virtual unsigned int getMaxTablesInSelect() = 0; + + virtual unsigned int getMaxUserNameLength() = 0; + + virtual const sql::SQLString& getNumericFunctions() = 0; + + virtual ResultSet * getPrimaryKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; + + virtual ResultSet * getProcedureColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern, const sql::SQLString& columnNamePattern) = 0; + + virtual ResultSet * getProcedures(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern) = 0; + + virtual const sql::SQLString& getProcedureTerm() = 0; + + virtual int getResultSetHoldability() = 0; + + virtual ResultSet * getSchemas() = 0; + + virtual const sql::SQLString& getSchemaTerm() = 0; + + virtual ResultSet * getSchemaCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0; + + virtual ResultSet * getSchemaCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0; + + virtual const sql::SQLString& getSearchStringEscape() = 0; + + virtual const sql::SQLString& getSQLKeywords() = 0; + + virtual int getSQLStateType() = 0; + + virtual const sql::SQLString& getStringFunctions() = 0; + + virtual ResultSet * getSuperTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; + + virtual ResultSet * getSuperTypes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern) = 0; + + virtual const sql::SQLString& getSystemFunctions() = 0; + + virtual ResultSet * getTablePrivileges(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; + + virtual ResultSet * getTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, std::list &types) = 0; + + virtual ResultSet * getTableTypes() = 0; + + virtual ResultSet * getTableCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; + + virtual ResultSet * getTableCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; + + virtual const sql::SQLString& getTimeDateFunctions() = 0; + + virtual ResultSet * getTypeInfo() = 0; + + virtual ResultSet * getUDTs(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, std::list &types) = 0; + + virtual SQLString getURL() = 0; + + virtual SQLString getUserName() = 0; + + virtual ResultSet * getVersionColumns(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; + + virtual bool insertsAreDetected(int type) = 0; + + virtual bool isCatalogAtStart() = 0; + + virtual bool isReadOnly() = 0; + + virtual bool locatorsUpdateCopy() = 0; + + virtual bool nullPlusNonNullIsNull() = 0; + + virtual bool nullsAreSortedAtEnd() = 0; + + virtual bool nullsAreSortedAtStart() = 0; + + virtual bool nullsAreSortedHigh() = 0; + + virtual bool nullsAreSortedLow() = 0; + + virtual bool othersDeletesAreVisible(int type) = 0; + + virtual bool othersInsertsAreVisible(int type) = 0; + + virtual bool othersUpdatesAreVisible(int type) = 0; + + virtual bool ownDeletesAreVisible(int type) = 0; + + virtual bool ownInsertsAreVisible(int type) = 0; + + virtual bool ownUpdatesAreVisible(int type) = 0; + + virtual bool storesLowerCaseIdentifiers() = 0; + + virtual bool storesLowerCaseQuotedIdentifiers() = 0; + + virtual bool storesMixedCaseIdentifiers() = 0; + + virtual bool storesMixedCaseQuotedIdentifiers() = 0; + + virtual bool storesUpperCaseIdentifiers() = 0; + + virtual bool storesUpperCaseQuotedIdentifiers() = 0; + + virtual bool supportsAlterTableWithAddColumn() = 0; + + virtual bool supportsAlterTableWithDropColumn() = 0; + + virtual bool supportsANSI92EntryLevelSQL() = 0; + + virtual bool supportsANSI92FullSQL() = 0; + + virtual bool supportsANSI92IntermediateSQL() = 0; + + virtual bool supportsBatchUpdates() = 0; + + virtual bool supportsCatalogsInDataManipulation() = 0; + + virtual bool supportsCatalogsInIndexDefinitions() = 0; + + virtual bool supportsCatalogsInPrivilegeDefinitions() = 0; + + virtual bool supportsCatalogsInProcedureCalls() = 0; + + virtual bool supportsCatalogsInTableDefinitions() = 0; + + virtual bool supportsColumnAliasing() = 0; + + virtual bool supportsConvert() = 0; + + virtual bool supportsConvert(int fromType, int toType) = 0; + + virtual bool supportsCoreSQLGrammar() = 0; + + virtual bool supportsCorrelatedSubqueries() = 0; + + virtual bool supportsDataDefinitionAndDataManipulationTransactions() = 0; + + virtual bool supportsDataManipulationTransactionsOnly() = 0; + + virtual bool supportsDifferentTableCorrelationNames() = 0; + + virtual bool supportsExpressionsInOrderBy() = 0; + + virtual bool supportsExtendedSQLGrammar() = 0; + + virtual bool supportsFullOuterJoins() = 0; + + virtual bool supportsGetGeneratedKeys() = 0; + + virtual bool supportsGroupBy() = 0; + + virtual bool supportsGroupByBeyondSelect() = 0; + + virtual bool supportsGroupByUnrelated() = 0; + + virtual bool supportsIntegrityEnhancementFacility() = 0; + + virtual bool supportsLikeEscapeClause() = 0; + + virtual bool supportsLimitedOuterJoins() = 0; + + virtual bool supportsMinimumSQLGrammar() = 0; + + virtual bool supportsMixedCaseIdentifiers() = 0; + + virtual bool supportsMixedCaseQuotedIdentifiers() = 0; + + virtual bool supportsMultipleOpenResults() = 0; + + virtual bool supportsMultipleResultSets() = 0; + + virtual bool supportsMultipleTransactions() = 0; + + virtual bool supportsNamedParameters() = 0; + + virtual bool supportsNonNullableColumns() = 0; + + virtual bool supportsOpenCursorsAcrossCommit() = 0; + + virtual bool supportsOpenCursorsAcrossRollback() = 0; + + virtual bool supportsOpenStatementsAcrossCommit() = 0; + + virtual bool supportsOpenStatementsAcrossRollback() = 0; + + virtual bool supportsOrderByUnrelated() = 0; + + virtual bool supportsOuterJoins() = 0; + + virtual bool supportsPositionedDelete() = 0; + + virtual bool supportsPositionedUpdate() = 0; + + virtual bool supportsResultSetConcurrency(int type, int concurrency) = 0; + + virtual bool supportsResultSetHoldability(int holdability) = 0; + + virtual bool supportsResultSetType(int type) = 0; + + virtual bool supportsSavepoints() = 0; + + virtual bool supportsSchemasInDataManipulation() = 0; + + virtual bool supportsSchemasInIndexDefinitions() = 0; + + virtual bool supportsSchemasInPrivilegeDefinitions() = 0; + + virtual bool supportsSchemasInProcedureCalls() = 0; + + virtual bool supportsSchemasInTableDefinitions() = 0; + + virtual bool supportsSelectForUpdate() = 0; + + virtual bool supportsStatementPooling() = 0; + + virtual bool supportsStoredProcedures() = 0; + + virtual bool supportsSubqueriesInComparisons() = 0; + + virtual bool supportsSubqueriesInExists() = 0; + + virtual bool supportsSubqueriesInIns() = 0; + + virtual bool supportsSubqueriesInQuantifieds() = 0; + + virtual bool supportsTableCorrelationNames() = 0; + + virtual bool supportsTransactionIsolationLevel(int level) = 0; + + virtual bool supportsTransactions() = 0; + + virtual bool supportsTypeConversion() = 0; /* SDBC */ + + virtual bool supportsUnion() = 0; + + virtual bool supportsUnionAll() = 0; + + virtual bool updatesAreDetected(int type) = 0; + + virtual bool usesLocalFilePerTable() = 0; + + virtual bool usesLocalFiles() = 0; + + virtual ResultSet *getSchemata(const sql::SQLString& catalogName = "") = 0; + + virtual ResultSet *getSchemaObjects(const sql::SQLString& catalogName = "", + const sql::SQLString& schemaName = "", + const sql::SQLString& objectType = "", + bool includingDdl = true, + const sql::SQLString& objectName = "", + const sql::SQLString& contextTableName = "") = 0; + + virtual ResultSet *getSchemaObjectTypes() = 0; +}; + + +} /* namespace sql */ + +#endif /* _SQL_METADATA_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/parameter_metadata.h b/Libraries/mysql-connector/include/jdbc/cppconn/parameter_metadata.h new file mode 100644 index 0000000..bc7f74a --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/parameter_metadata.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_PARAMETER_METADATA_H_ +#define _SQL_PARAMETER_METADATA_H_ + +#include "sqlstring.h" + + +namespace sql +{ + +class ParameterMetaData +{ +public: + enum + { + parameterModeIn, + parameterModeInOut, + parameterModeOut, + parameterModeUnknown + }; + enum + { + parameterNoNulls, + parameterNullable, + parameterNullableUnknown + }; + + virtual sql::SQLString getParameterClassName(unsigned int param) = 0; + + virtual int getParameterCount() = 0; + + virtual int getParameterMode(unsigned int param) = 0; + + virtual int getParameterType(unsigned int param) = 0; + + virtual sql::SQLString getParameterTypeName(unsigned int param) = 0; + + virtual int getPrecision(unsigned int param) = 0; + + virtual int getScale(unsigned int param) = 0; + + virtual int isNullable(unsigned int param) = 0; + + virtual bool isSigned(unsigned int param) = 0; + +protected: + virtual ~ParameterMetaData() {} +}; + + +} /* namespace sql */ + +#endif /* _SQL_PARAMETER_METADATA_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/prepared_statement.h b/Libraries/mysql-connector/include/jdbc/cppconn/prepared_statement.h new file mode 100644 index 0000000..265b412 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/prepared_statement.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + + +#ifndef _SQL_PREPARED_STATEMENT_H_ +#define _SQL_PREPARED_STATEMENT_H_ + +#include +#include "statement.h" + + +namespace sql +{ + +class Connection; +class ResultSet; +class ResultSetMetaData; +class ParameterMetaData; + +class PreparedStatement : public Statement +{ +public: + virtual ~PreparedStatement() {} + + virtual void clearParameters() = 0; + + virtual bool execute(const sql::SQLString& sql) = 0; + virtual bool execute() = 0; + + virtual ResultSet *executeQuery(const sql::SQLString& sql) = 0; + virtual ResultSet *executeQuery() = 0; + + virtual int executeUpdate(const sql::SQLString& sql) = 0; + virtual int executeUpdate() = 0; + + virtual ResultSetMetaData * getMetaData() = 0; + + virtual ParameterMetaData * getParameterMetaData() = 0; + + virtual bool getMoreResults() = 0; + + virtual void setBigInt(unsigned int parameterIndex, const sql::SQLString& value) = 0; + + virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0; + + virtual void setBoolean(unsigned int parameterIndex, bool value) = 0; + + virtual void setDateTime(unsigned int parameterIndex, const sql::SQLString& value) = 0; + + virtual void setDouble(unsigned int parameterIndex, double value) = 0; + + virtual void setInt(unsigned int parameterIndex, int32_t value) = 0; + + virtual void setUInt(unsigned int parameterIndex, uint32_t value) = 0; + + virtual void setInt64(unsigned int parameterIndex, int64_t value) = 0; + + virtual void setUInt64(unsigned int parameterIndex, uint64_t value) = 0; + + virtual void setNull(unsigned int parameterIndex, int sqlType) = 0; + + virtual void setString(unsigned int parameterIndex, const sql::SQLString& value) = 0; + + virtual PreparedStatement * setResultSetType(sql::ResultSet::enum_type type) = 0; + + virtual void setVector(unsigned int parameterIndex, const std::vector& value) = 0; + +}; + + +} /* namespace sql */ + +#endif /* _SQL_PREPARED_STATEMENT_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/resultset.h b/Libraries/mysql-connector/include/jdbc/cppconn/resultset.h new file mode 100644 index 0000000..90d988a --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/resultset.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_RESULTSET_H_ +#define _SQL_RESULTSET_H_ + +#include "config.h" + +#include +#include +#include +#include +#include "sqlstring.h" +#include "resultset_metadata.h" + + +namespace sql +{ + +class Statement; + +class RowID +{ +public: + virtual ~RowID() {} +}; + +class ResultSet +{ +public: + enum + { + CLOSE_CURSORS_AT_COMMIT, + HOLD_CURSORS_OVER_COMMIT + }; + enum + { + CONCUR_READ_ONLY, + CONCUR_UPDATABLE + }; + enum + { + FETCH_FORWARD, + FETCH_REVERSE, + FETCH_UNKNOWN + }; + typedef enum + { + TYPE_FORWARD_ONLY, + TYPE_SCROLL_INSENSITIVE, + TYPE_SCROLL_SENSITIVE + } enum_type; + + virtual ~ResultSet() {} + + virtual bool absolute(int row) = 0; + + virtual void afterLast() = 0; + + virtual void beforeFirst() = 0; + + virtual void cancelRowUpdates() = 0; + + virtual void clearWarnings() = 0; + + virtual void close() = 0; + + virtual uint32_t findColumn(const sql::SQLString& columnLabel) const = 0; + + virtual bool first() = 0; + + virtual std::istream * getBlob(uint32_t columnIndex) const = 0; + virtual std::istream * getBlob(const sql::SQLString& columnLabel) const = 0; + + virtual bool getBoolean(uint32_t columnIndex) const = 0; + virtual bool getBoolean(const sql::SQLString& columnLabel) const = 0; + + virtual int getConcurrency() = 0; + virtual SQLString getCursorName() = 0; + + virtual long double getDouble(uint32_t columnIndex) const = 0; + virtual long double getDouble(const sql::SQLString& columnLabel) const = 0; + + virtual int getFetchDirection() = 0; + virtual size_t getFetchSize() = 0; + virtual int getHoldability() = 0; + + virtual int32_t getInt(uint32_t columnIndex) const = 0; + virtual int32_t getInt(const sql::SQLString& columnLabel) const = 0; + + virtual uint32_t getUInt(uint32_t columnIndex) const = 0; + virtual uint32_t getUInt(const sql::SQLString& columnLabel) const = 0; + + virtual int64_t getInt64(uint32_t columnIndex) const = 0; + virtual int64_t getInt64(const sql::SQLString& columnLabel) const = 0; + + virtual uint64_t getUInt64(uint32_t columnIndex) const = 0; + virtual uint64_t getUInt64(const sql::SQLString& columnLabel) const = 0; + + virtual ResultSetMetaData * getMetaData() const = 0; + + virtual size_t getRow() const = 0; + + virtual RowID * getRowId(uint32_t columnIndex) = 0; + virtual RowID * getRowId(const sql::SQLString & columnLabel) = 0; + + virtual const Statement * getStatement() const = 0; + + virtual SQLString getString(uint32_t columnIndex) const = 0; + virtual SQLString getString(const sql::SQLString& columnLabel) const = 0; + + virtual enum_type getType() const = 0; + + virtual void getWarnings() = 0; + + virtual void insertRow() = 0; + + virtual bool isAfterLast() const = 0; + + virtual bool isBeforeFirst() const = 0; + + virtual bool isClosed() const = 0; + + virtual bool isFirst() const = 0; + + virtual bool isLast() const = 0; + + virtual bool isNull(uint32_t columnIndex) const = 0; + virtual bool isNull(const sql::SQLString& columnLabel) const = 0; + + virtual bool last() = 0; + + virtual bool next() = 0; + + virtual void moveToCurrentRow() = 0; + + virtual void moveToInsertRow() = 0; + + virtual bool previous() = 0; + + virtual void refreshRow() = 0; + + virtual bool relative(int rows) = 0; + + virtual bool rowDeleted() = 0; + + virtual bool rowInserted() = 0; + + virtual bool rowUpdated() = 0; + + virtual void setFetchSize(size_t rows) = 0; + + virtual size_t rowsCount() const = 0; + + virtual bool wasNull() const = 0; + + virtual std::vector getVector(uint32_t columnIndex) const = 0; + virtual std::vector getVector(const sql::SQLString &columnLabel) const = 0; +}; + +} /* namespace sql */ + +#endif /* _SQL_RESULTSET_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/resultset_metadata.h b/Libraries/mysql-connector/include/jdbc/cppconn/resultset_metadata.h new file mode 100644 index 0000000..647ab7a --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/resultset_metadata.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_RESULTSET_METADATA_H_ +#define _SQL_RESULTSET_METADATA_H_ + +#include "sqlstring.h" +#include "datatype.h" + +namespace sql +{ + +class ResultSetMetaData +{ +public: + enum + { + columnNoNulls, + columnNullable, + columnNullableUnknown + }; + + virtual SQLString getCatalogName(unsigned int column) = 0; + + virtual unsigned int getColumnCount() = 0; + + virtual unsigned int getColumnDisplaySize(unsigned int column) = 0; + + virtual SQLString getColumnLabel(unsigned int column) = 0; + + virtual SQLString getColumnName(unsigned int column) = 0; + + virtual int getColumnType(unsigned int column) = 0; + + virtual SQLString getColumnTypeName(unsigned int column) = 0; + + virtual SQLString getColumnCharset(unsigned int columnIndex) = 0; + + virtual SQLString getColumnCollation(unsigned int columnIndex) = 0; + + virtual unsigned int getPrecision(unsigned int column) = 0; + + virtual unsigned int getScale(unsigned int column) = 0; + + virtual SQLString getSchemaName(unsigned int column) = 0; + + virtual SQLString getTableName(unsigned int column) = 0; + + virtual bool isAutoIncrement(unsigned int column) = 0; + + virtual bool isCaseSensitive(unsigned int column) = 0; + + virtual bool isCurrency(unsigned int column) = 0; + + virtual bool isDefinitelyWritable(unsigned int column) = 0; + + virtual int isNullable(unsigned int column) = 0; + + virtual bool isNumeric(unsigned int column) = 0; + + virtual bool isReadOnly(unsigned int column) = 0; + + virtual bool isSearchable(unsigned int column) = 0; + + virtual bool isSigned(unsigned int column) = 0; + + virtual bool isWritable(unsigned int column) = 0; + + virtual bool isZerofill(unsigned int column) = 0; + +protected: + virtual ~ResultSetMetaData() {} +}; + + +} /* namespace sql */ + +#endif /* _SQL_RESULTSET_METADATA_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/sqlstring.h b/Libraries/mysql-connector/include/jdbc/cppconn/sqlstring.h new file mode 100644 index 0000000..26d62e6 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/sqlstring.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_STRING_H_ +#define _SQL_STRING_H_ + +#include +#include +#include "build_config.h" +#include + +namespace sql +{ + class SQLString + { +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable: 4251) +#endif + std::string realStr; +#ifdef _WIN32 +#pragma warning(pop) +#endif + + public: +#ifdef _WIN32 + //TODO something less dirty-hackish. + static const size_t npos = static_cast(-1); +#else + static const size_t npos = std::string::npos; +#endif + + ~SQLString() {} + + SQLString() {} + + SQLString(const SQLString & other) : realStr(other.realStr) {} + + SQLString(const std::string & other) : realStr(other) {} + + SQLString(const char other[]) : realStr(other) {} + + SQLString(const char * s, size_t n) : realStr(s, n) {} + + // Needed for stuff like SQLString str= "char * string constant" + const SQLString & operator=(const char * s) + { + realStr = s; + return *this; + } + + const SQLString & operator=(const std::string & rhs) + { + realStr = rhs; + return *this; + } + + const SQLString & operator=(const SQLString & rhs) + { + realStr = rhs.realStr; + return *this; + } + + // Conversion to st::string. Comes in play for stuff like std::string str= SQLString_var; + operator const std::string &() const + { + return realStr; + } + + /** For access std::string methods. Not sure we need it. Makes it look like some smart ptr. + possibly operator* - will look even more like smart ptr */ + std::string * operator ->() + { + return & realStr; + } + + int compare(const SQLString& str) const + { + return realStr.compare(str.realStr); + } + + int compare(const char * s) const + { + return realStr.compare(s); + } + + int compare(size_t pos1, size_t n1, const char * s) const + { + return realStr.compare(pos1, n1, s); + } + + int caseCompare(const SQLString &s) const + { + std::string tmp(realStr), str(s); + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + return tmp.compare(str); + } + + int caseCompare(const char * s) const + { + std::string tmp(realStr), str(s); + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + return tmp.compare(str); + } + + int caseCompare(size_t pos1, size_t n1, const char * s) const + { + std::string tmp(realStr.c_str() + pos1, n1), str(s); + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + return tmp.compare(str); + } + + const std::string & asStdString() const + { + return realStr; + } + + const char * c_str() const + { + return realStr.c_str(); + } + + size_t length() const + { + return realStr.length(); + } + + SQLString & append(const std::string & str) + { + realStr.append(str); + return *this; + } + + SQLString & append(const char * s) + { + realStr.append(s); + return *this; + } + + const char& operator[](size_t pos) const + { + return realStr[pos]; + } + + size_t find(char c, size_t pos = 0) const + { + return realStr.find(c, pos); + } + + size_t find(const SQLString & s, size_t pos = 0) const + { + return realStr.find(s.realStr, pos); + } + + SQLString substr(size_t pos = 0, size_t n = npos) const + { + return realStr.substr(pos, n); + } + + const SQLString& replace(size_t pos1, size_t n1, const SQLString & s) + { + realStr.replace(pos1, n1, s.realStr); + return *this; + } + + size_t find_first_of(char c, size_t pos = 0) const + { + return realStr.find_first_of(c, pos); + } + + size_t find_last_of(char c, size_t pos = npos) const + { + return realStr.find_last_of(c, pos); + } + + const SQLString & operator+=(const SQLString & op2) + { + realStr += op2.realStr; + return *this; + } +}; + + +/* + Operators that can and have to be not a member. +*/ +inline const SQLString operator+(const SQLString & op1, const SQLString & op2) +{ + return sql::SQLString(op1.asStdString() + op2.asStdString()); +} + +inline bool operator ==(const SQLString & op1, const SQLString & op2) +{ + return (op1.asStdString() == op2.asStdString()); +} + +inline bool operator !=(const SQLString & op1, const SQLString & op2) +{ + return (op1.asStdString() != op2.asStdString()); +} + +inline bool operator <(const SQLString & op1, const SQLString & op2) +{ + return op1.asStdString() < op2.asStdString(); +} + + +}// namespace sql + + +namespace std +{ + // operator << for SQLString output + inline ostream & operator << (ostream & os, const sql::SQLString & str ) + { + return os << str.asStdString(); + } +} +#endif diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/statement.h b/Libraries/mysql-connector/include/jdbc/cppconn/statement.h new file mode 100644 index 0000000..704bcde --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/statement.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_STATEMENT_H_ +#define _SQL_STATEMENT_H_ + +#include "config.h" +#include "resultset.h" + +#include + +namespace sql +{ + +class ResultSet; +class Connection; +class SQLWarning; + + +class Statement +{ +public: + virtual ~Statement() {}; + + virtual Connection * getConnection() = 0; + + virtual void cancel() = 0; + + virtual void clearWarnings() = 0; + + virtual void close() = 0; + + virtual bool execute(const sql::SQLString& sql) = 0; + + virtual ResultSet * executeQuery(const sql::SQLString& sql) = 0; + + virtual int executeUpdate(const sql::SQLString& sql) = 0; + + virtual size_t getFetchSize() = 0; + + virtual unsigned int getMaxFieldSize() = 0; + + virtual uint64_t getMaxRows() = 0; + + virtual bool getMoreResults() = 0; + + virtual unsigned int getQueryTimeout() = 0; + + virtual ResultSet * getResultSet() = 0; + + virtual sql::ResultSet::enum_type getResultSetType() = 0; + + virtual uint64_t getUpdateCount() = 0; + + virtual const SQLWarning * getWarnings() = 0; + + virtual void setCursorName(const sql::SQLString & name) = 0; + + virtual void setEscapeProcessing(bool enable) = 0; + + virtual void setFetchSize(size_t rows) = 0; + + virtual void setMaxFieldSize(unsigned int max) = 0; + + virtual void setMaxRows(unsigned int max) = 0; + + virtual void setQueryTimeout(unsigned int seconds) = 0; + + virtual Statement * setResultSetType(sql::ResultSet::enum_type type) = 0; + + virtual int setQueryAttrBigInt(const sql::SQLString &name, const sql::SQLString& value) = 0; + virtual int setQueryAttrBoolean(const sql::SQLString &name, bool value) = 0; + virtual int setQueryAttrDateTime(const sql::SQLString &name, const sql::SQLString& value) = 0; + virtual int setQueryAttrDouble(const sql::SQLString &name, double value) = 0; + virtual int setQueryAttrInt(const sql::SQLString &name, int32_t value) = 0; + virtual int setQueryAttrUInt(const sql::SQLString &name, uint32_t value) = 0; + virtual int setQueryAttrInt64(const sql::SQLString &name, int64_t value) = 0; + virtual int setQueryAttrUInt64(const sql::SQLString &name, uint64_t value) = 0; + virtual int setQueryAttrNull(const sql::SQLString &name) = 0; + virtual int setQueryAttrString(const sql::SQLString &name, const sql::SQLString& value) = 0; + + virtual void clearAttributes() = 0; + +}; + +} /* namespace sql */ + +#endif /* _SQL_STATEMENT_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/variant.h b/Libraries/mysql-connector/include/jdbc/cppconn/variant.h new file mode 100644 index 0000000..add0098 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/variant.h @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_VARIANT_H_ +#define _SQL_VARIANT_H_ + +#include +#include +#include +#include +#include + +#include "build_config.h" +#include "sqlstring.h" +#include "exception.h" + +namespace sql +{ + +class BaseVariantImpl +{ +public: + BaseVariantImpl (void *ptr, sql::SQLString vtype) : + cvptr(ptr), + vTypeName(vtype) + {} + + virtual ~BaseVariantImpl() { + cvptr=NULL; + } + + virtual BaseVariantImpl* Clone()=0; + + template + T* get() const { + if (typeid(T).name() == typeid(void).name()) { + return static_cast< T * > (cvptr); + } + + if ((vTypeName == typeid(std::string).name() && + typeid(T).name() == typeid(sql::SQLString).name()) || + (vTypeName == typeid(sql::SQLString).name() && + typeid(T).name() == typeid(std::string).name()) || + (vTypeName == typeid(std::map< std::string, std::string >).name() && + typeid(T).name() == + typeid(std::map< sql::SQLString, sql::SQLString >).name()) || + (vTypeName == + typeid(std::map< sql::SQLString, sql::SQLString >).name() && + typeid(T).name() == + typeid(std::map< std::string, std::string >).name()) || + (vTypeName == typeid(std::list< std::string >).name() && + typeid(T).name() == + typeid(std::list< sql::SQLString >).name()) || + (vTypeName == + typeid(std::list< sql::SQLString >).name() && + typeid(T).name() == + typeid(std::list< std::string >).name())) + { + return static_cast< T * > (cvptr); + } + + if (typeid(T).name() != vTypeName) { + throw sql::InvalidArgumentException("Variant type doesn't match."); + } + + return static_cast< T * > (cvptr); + } + +protected: + void *cvptr; + sql::SQLString vTypeName; +}; + + +template +class VariantImpl : public BaseVariantImpl +{ +public: + VariantImpl(T i) : BaseVariantImpl(new T(i), typeid(i).name()) {} + + ~VariantImpl() { + destroy_content(); + } + + VariantImpl(VariantImpl& that) : BaseVariantImpl(that) { + copy_content(that); + } + + VariantImpl& operator=(VariantImpl& that) { + if (this != &that) { + destroy_content(); + if (cvptr == NULL) { + copy_content(that); + } + } + return *this; + } + + virtual VariantImpl* Clone() { + return new VariantImpl(*this); + } + +private: + + void destroy_content() { + T *tmp=static_cast< T * >(cvptr); + if (tmp) { + delete tmp; + cvptr=NULL; + } + } + + void copy_content(BaseVariantImpl& that) { + cvptr=new T (*(static_cast< T * > (that.get< void >()))); + } +}; + + +template +class VariantMap : public BaseVariantImpl +{ +public: + VariantMap(T i) : BaseVariantImpl(new T(i), typeid(i).name()) {} + + ~VariantMap() { + destroy_content(); + } + + VariantMap(VariantMap& that) : BaseVariantImpl(that) { + if (this != &that) { + copy_content(that); + } + } + + VariantMap& operator=(VariantMap& that) { + if (this != &that) { + destroy_content(); + copy_content(that); + } + return *this; + } + + virtual VariantMap* Clone() { + return new VariantMap(*this); + } + + +private: + void destroy_content() { + T *tmp=static_cast< T *> (cvptr); + if (tmp) { + tmp->clear(); + delete tmp; + cvptr=NULL; + } + } + + void copy_content(VariantMap& var) { + T *tmp=static_cast< T *> (var.cvptr); + if (tmp) { + cvptr=new T(); + typename T::const_iterator cit=tmp->begin(); + while(cit != tmp->end()) { + (static_cast< T * >(cvptr))->insert( + std::make_pair(sql::SQLString(cit->first), + sql::SQLString(cit->second))); + ++cit; + } + } + } +}; + + +template +class VariantList : public BaseVariantImpl +{ +public: + VariantList(T i) : BaseVariantImpl(new T(i), typeid(i).name()) {} + + ~VariantList() { + destroy_content(); + } + + VariantList(VariantList& that) : BaseVariantImpl(that) { + if (this != &that) { + copy_content(that); + } + } + + VariantList& operator=(VariantList& that) { + if (this != &that) { + destroy_content(); + copy_content(that); + } + return *this; + } + + virtual VariantList* Clone() { + return new VariantList(*this); + } + + +private: + void destroy_content() + { + T *tmp=static_cast< T *> (cvptr); + if (tmp) { + tmp->clear(); + delete tmp; + cvptr=NULL; + } + } + + void copy_content(VariantList& var) + { + T *tmp=static_cast< T *> (var.cvptr); + if (tmp) { + cvptr=new T(); + typename T::const_iterator cit=tmp->begin(); + while(cit != tmp->end()) { + (static_cast< T * >(cvptr))->push_back(sql::SQLString(*cit)); + ++cit; + } + } + } +}; + + +class CPPCONN_PUBLIC_FUNC Variant +{ +public: + Variant(const int &i=0) : + variant(new VariantImpl< int >(i)) {} + + Variant(const double &i) : + variant(new VariantImpl< double >(i)) {} + + Variant(const bool &i) : + variant(new VariantImpl< bool >(i)) {} + + Variant(const char* i) : + variant(new VariantImpl< sql::SQLString >(i)) {} + + Variant(const std::string &i) : + variant(new VariantImpl< sql::SQLString >(i)) {} + + Variant(const sql::SQLString &i) : + variant(new VariantImpl< sql::SQLString >(i)) {} + + Variant(const std::list< std::string > &i) : + variant(new VariantList< std::list < std::string > >(i)) {} + + Variant(const std::list< sql::SQLString > &i) : + variant(new VariantList< std::list < sql::SQLString > >(i)) {} + + Variant(const std::map< std::string, std::string > &i) : + variant(new VariantMap< std::map< std::string, std::string > >(i)) {} + + Variant(const std::map< sql::SQLString, sql::SQLString > &i) : + variant(new VariantMap< std::map< sql::SQLString, sql::SQLString > >(i)) {} + + ~Variant() { + if (variant) { + delete variant; + variant=0; + } + } + + Variant(const Variant& that) { + if (this != &that) { + variant=that.variant->Clone(); + } + } + + Variant& operator=(const Variant& that) { + if (this != &that) { + delete variant; + variant=that.variant->Clone(); + } + return *this; + } + + template + T* get() const { + return variant->get(); + } + +private: + BaseVariantImpl *variant; +}; + + +} /* namespace sql */ + +#endif /* _SQL_VARIANT_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/version_info.h b/Libraries/mysql-connector/include/jdbc/cppconn/version_info.h new file mode 100644 index 0000000..567202d --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/version_info.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* */ + +#define MYCPPCONN_DM_MAJOR_VERSION 9 +#define MYCPPCONN_DM_MINOR_VERSION 0 +#define MYCPPCONN_DM_PATCH_VERSION 0 + +#define MYCPPCONN_DM_VERSION "9.0.0" +#define MYCPPCONN_DM_VERSION_ID 9000000 +#define MYSQL_CONCPP_LICENSE "GPL-2.0" + +#define MYSQL_CONCPP_VERSION_MAJOR 9 +#define MYSQL_CONCPP_VERSION_MINOR 0 +#define MYSQL_CONCPP_VERSION_MICRO 0 + +#define MYSQL_CONCPP_VERSION_NUMBER 9000000 + + +/* Driver version info */ + +#define MYCPPCONN_STATIC_MYSQL_VERSION "9.0.0" +#define MYCPPCONN_STATIC_MYSQL_VERSION_ID 90000 + +#define MYCPPCONN_BOOST_VERSION diff --git a/Libraries/mysql-connector/include/jdbc/cppconn/warning.h b/Libraries/mysql-connector/include/jdbc/cppconn/warning.h new file mode 100644 index 0000000..2aeb20c --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/cppconn/warning.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _SQL_WARNING_H_ +#define _SQL_WARNING_H_ + + +#include +#include +#include +#include "sqlstring.h" + +namespace sql +{ + +#ifdef _WIN32 +#pragma warning (disable : 4290) +//warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +class SQLWarning +{ +public: + + SQLWarning(){} + + virtual const sql::SQLString & getMessage() const = 0; + + virtual const sql::SQLString & getSQLState() const = 0; + + virtual int getErrorCode() const = 0; + + virtual const SQLWarning * getNextWarning() const = 0; + + virtual void setNextWarning(const SQLWarning * _next) = 0; + +protected: + + virtual ~SQLWarning(){}; + + SQLWarning(const SQLWarning&){}; + +private: + const SQLWarning & operator = (const SQLWarning & rhs); + +}; + + +} /* namespace sql */ + +#endif /* _SQL_WARNING_H_ */ diff --git a/Libraries/mysql-connector/include/jdbc/mysql_connection.h b/Libraries/mysql-connector/include/jdbc/mysql_connection.h new file mode 100644 index 0000000..7b78202 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/mysql_connection.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _MYSQL_CONNECTION_H_ +#define _MYSQL_CONNECTION_H_ + +#include "cppconn/connection.h" +#include + +#if(_WIN32 && CONCPP_BUILD_SHARED) +extern std::string driver_dll_path; +#endif + +namespace sql +{ +namespace mysql +{ + +class CPPCONN_PUBLIC_FUNC MySQL_Savepoint : public sql::Savepoint +{ + sql::SQLString name; + +public: + MySQL_Savepoint(const sql::SQLString &savepoint); + virtual ~MySQL_Savepoint() {} + + int getSavepointId(); + + sql::SQLString getSavepointName(); + +private: + /* Prevent use of these */ + MySQL_Savepoint(const MySQL_Savepoint &); + void operator=(MySQL_Savepoint &); +}; + + +class MySQL_DebugLogger; +struct MySQL_ConnectionData; /* PIMPL */ +class MySQL_Statement; +class MySQL_Prepared_Statement; + +namespace NativeAPI +{ +class NativeConnectionWrapper; +} + +class CPPCONN_PUBLIC_FUNC MySQL_Connection : public sql::Connection +{ + friend MySQL_Statement; + friend MySQL_Prepared_Statement; + + MySQL_Statement * createServiceStmt(); + +public: + MySQL_Connection(Driver * _driver, + ::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy, + const sql::SQLString& hostName, + const sql::SQLString& userName, + const sql::SQLString& password); + + MySQL_Connection(Driver * _driver, ::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy, + std::map< sql::SQLString, sql::ConnectPropertyVal > & options); + + virtual ~MySQL_Connection(); + + void clearWarnings(); + + void close(); + + void commit(); + + sql::Statement * createStatement(); + + sql::SQLString escapeString(const sql::SQLString &); + + bool getAutoCommit(); + + sql::SQLString getCatalog(); + + Driver *getDriver(); + + sql::SQLString getSchema(); + + sql::SQLString getClientInfo(); + + void getClientOption(const sql::SQLString & optionName, void * optionValue); + + sql::SQLString getClientOption(const sql::SQLString & optionName); + + sql::DatabaseMetaData * getMetaData(); + + enum_transaction_isolation getTransactionIsolation(); + + const SQLWarning * getWarnings(); + + bool isClosed(); + + bool isReadOnly(); + + bool isValid(); + + bool reconnect(); + + sql::SQLString nativeSQL(const sql::SQLString& sql); + + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql); + + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys); + + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int columnIndexes[]); + + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency); + + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability); + + sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]); + + void releaseSavepoint(Savepoint * savepoint) ; + + void rollback(); + + void rollback(Savepoint * savepoint); + + void setAutoCommit(bool autoCommit); + + void setCatalog(const sql::SQLString& catalog); + + void setSchema(const sql::SQLString& catalog); + + sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue); + + sql::Connection * setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue); + + void setHoldability(int holdability); + + void setReadOnly(bool readOnly); + + sql::Savepoint * setSavepoint(); + + sql::Savepoint * setSavepoint(const sql::SQLString& name); + + void setTransactionIsolation(enum_transaction_isolation level); + + virtual sql::SQLString getSessionVariable(const sql::SQLString & varname); + + virtual void setSessionVariable(const sql::SQLString & varname, const sql::SQLString & value); + + virtual void setSessionVariable(const sql::SQLString & varname, unsigned int value); + + virtual sql::SQLString getLastStatementInfo(); + + sql::SQLString getCurrentUser(); + +private: + /* We do not really think this class has to be subclassed*/ + void checkClosed(); + void init(std::map< sql::SQLString, sql::ConnectPropertyVal > & properties); + + Driver * driver; + +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable: 4251) +#endif + std::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy; +#ifdef _WIN32 +#pragma warning(pop) +#endif + + /* statement handle to execute queries initiated by driver. Perhaps it is + a good idea to move it to a separate helper class */ +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable: 4251) +#endif + std::unique_ptr< ::sql::mysql::MySQL_Statement > service; + + std::unique_ptr< ::sql::mysql::MySQL_ConnectionData > intern; /* pimpl */ +#ifdef _WIN32 +#pragma warning(pop) +#endif + + /* We need to store the user name for telemetry */ + SQLString currentUser; + + /* Prevent use of these */ + MySQL_Connection(const MySQL_Connection &); + void operator=(MySQL_Connection &); +}; + +} /* namespace mysql */ +} /* namespace sql */ + +#endif // _MYSQL_CONNECTION_H_ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/Libraries/mysql-connector/include/jdbc/mysql_driver.h b/Libraries/mysql-connector/include/jdbc/mysql_driver.h new file mode 100644 index 0000000..f764304 --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/mysql_driver.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _MYSQL_DRIVER_H_ +#define _MYSQL_DRIVER_H_ + + +#include "cppconn/driver.h" + +#include + +extern "C" +{ +CPPCONN_PUBLIC_FUNC void * sql_mysql_get_driver_instance(); +} + +namespace sql +{ +namespace mysql +{ +namespace NativeAPI +{ + class NativeDriverWrapper; +} + +//class sql::mysql::NativeAPI::NativeDriverWrapper; + +class CPPCONN_PUBLIC_FUNC MySQL_Driver : public sql::Driver +{ +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable: 4251) +#endif + std::unique_ptr< ::sql::mysql::NativeAPI::NativeDriverWrapper > proxy; +#ifdef _WIN32 +#pragma warning(pop) +#endif + + /* + Note: With current implementation `fido_callback` and `fido_callback_store` + are not really used and should be removed after deprecation of Fido + authentication plugin and when ABI can be changed. + */ + + ::sql::Fido_Callback* fido_callback = nullptr; + ::sql::Fido_Callback fido_callback_store; + + /* + Callback function to be called by WebAuthn authentication plugin to notify + the user. + + Note: The `fido_callback` pointer is re-used as a flag to indicate if + the callback was set by a user and its type (WebAuthn vs. Fido). + */ + + std::function webauthn_callback; + +public: + MySQL_Driver(); + MySQL_Driver(const ::sql::SQLString & clientLib); + + virtual ~MySQL_Driver(); + + sql::Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) override; + + sql::Connection * connect(sql::ConnectOptionsMap & options) override; + + int getMajorVersion() override; + + int getMinorVersion() override; + + int getPatchVersion() override; + + const sql::SQLString & getName() override; + + void setCallBack(sql::Fido_Callback &cb) override; + void setCallBack(sql::Fido_Callback &&cb) override; + + void setCallBack(sql::WebAuthn_Callback &cb) override; + void setCallBack(sql::WebAuthn_Callback &&cb) override; + + void threadInit() override; + + void threadEnd() override; + +private: + /* Prevent use of these */ + MySQL_Driver(const MySQL_Driver &); + void operator=(MySQL_Driver &); + + struct WebAuthn_Callback_Setter; + + friend WebAuthn_Callback_Setter; + friend MySQL_Connection; + +}; + +/** We do not hide the function if MYSQLCLIENT_STATIC_BINDING(or anything else) not defined + because the counterpart C function is declared in the cppconn and is always visible. + If dynamic loading is not enabled then its result is just like of get_driver_instance() +*/ + +CPPCONN_PUBLIC_FUNC MySQL_Driver * _get_driver_instance_by_name(const char * const clientlib); + +inline static MySQL_Driver * get_driver_instance_by_name(const char * const clientlib) +{ + check_lib(); + return sql::mysql::_get_driver_instance_by_name(clientlib); +} + +inline static MySQL_Driver * get_driver_instance() +{ + return sql::mysql::get_driver_instance_by_name(""); +} + +inline static MySQL_Driver *get_mysql_driver_instance() { return get_driver_instance(); } + +} /* namespace mysql */ +} /* namespace sql */ + +#endif // _MYSQL_DRIVER_H_ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/Libraries/mysql-connector/include/jdbc/mysql_error.h b/Libraries/mysql-connector/include/jdbc/mysql_error.h new file mode 100644 index 0000000..863754c --- /dev/null +++ b/Libraries/mysql-connector/include/jdbc/mysql_error.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#ifndef _MYSQL_ERROR_H_ +#define _MYSQL_ERROR_H_ + +namespace sql +{ +namespace mysql +{ + /* Driver specific errors */ + enum DRIVER_ERROR { + /* Underlying client library(cl) can't deal with expired password. + Raised when password actually expires */ + deCL_CANT_HANDLE_EXP_PWD= 820 + }; +} /* namespace mysql */ +} /* namespace sql */ + +#endif /* _MYSQL_ERROR_H_ */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/Libraries/mysql-connector/include/mysql/jdbc.h b/Libraries/mysql-connector/include/mysql/jdbc.h new file mode 100644 index 0000000..3ce9347 --- /dev/null +++ b/Libraries/mysql-connector/include/mysql/jdbc.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "../jdbc/mysql_connection.h" +#include "../jdbc/mysql_driver.h" +#include "../jdbc/mysql_error.h" +#include "../jdbc/cppconn/build_config.h" +#include "../jdbc/cppconn/callback.h" +#include "../jdbc/cppconn/config.h" +#include "../jdbc/cppconn/connection.h" +#include "../jdbc/cppconn/datatype.h" +#include "../jdbc/cppconn/driver.h" +#include "../jdbc/cppconn/exception.h" +#include "../jdbc/cppconn/metadata.h" +#include "../jdbc/cppconn/parameter_metadata.h" +#include "../jdbc/cppconn/prepared_statement.h" +#include "../jdbc/cppconn/resultset.h" +#include "../jdbc/cppconn/resultset_metadata.h" +#include "../jdbc/cppconn/statement.h" +#include "../jdbc/cppconn/sqlstring.h" +#include "../jdbc/cppconn/warning.h" +#include "../jdbc/cppconn/version_info.h" +#include "../jdbc/cppconn/variant.h" diff --git a/Libraries/mysql-connector/include/mysqlx/common.h b/Libraries/mysql-connector/include/mysqlx/common.h new file mode 100644 index 0000000..a52429d --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/common.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQL_COMMON_H +#define MYSQL_COMMON_H + +#undef min +#undef max + +//disable c++17 iterator warnings +#define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING + +/* + Common definitions and declarations that are needed by public headers. + + Note: Any common stuff that is needed only by the implementation, should be + kept in the common/ folder, either as headers or source files. +*/ + +#include "common_constants.h" +#include "common/api.h" +#include "common/error.h" +#include "common/util.h" +#include "common/value.h" +#include "common/settings.h" + +PUSH_SYS_WARNINGS +#include +POP_SYS_WARNINGS + +/* + On Windows, dependency on the sockets library can be handled using + #pragma comment directive. +*/ + +#ifdef _WIN32 +#pragma comment(lib,"ws2_32") +#endif + + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/common/api.h b/Libraries/mysql-connector/include/mysqlx/common/api.h new file mode 100644 index 0000000..90803d4 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/common/api.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_COMMON_API_H +#define MYSQLX_COMMON_API_H + + +/* + X DevAPI ABI version and revision + ================================= + + All public symbols inside mysqlx namespace should be defined inside + MYSQLX_ABI_BEGIN(X,Y) ... MYSQLX_ABI_END(X,Y) block, where X.Y is the + ABI version of the symbol. This puts the symbol inside mysqlx::abiX::rY + namespace. + + The current ABI version is determined by MYSQLX_ABI_X_Y macros below. Using + inline namespace ensures that symbol reference mysqlx::foo resolves + to mysqlx::abiX::rY::foo, where X.Y is the current ABI version. + + Declarations below ensure, that each ABI revision namespace includes all + symbols from previous revisions (via using namespace declaration). + + If the same symbol is defined for several revisions of the ABI, the latest + one will shadow other definitions but earlier revisions will be also present + to be used by old code. This way backward ABI compatibility can be maintained. +*/ + +/* + When new ABI version or revision is added, the corresponding + MYSQLX_ABI_MAJOR/MINOR_X macro needs to be added below. The macros for the + latest ABI version and revision should expand to "inline", other MSQLX_ABI_* + macros should have empty expansion. For example, + after adding revision ABI 2.1 these macros should look as follows: + + #define MYSQLX_ABI_MAJOR_2 inline // current ABI version + #define MYSQLX_ABI_MINOR_0 + #define MYSQLX_ABI_MINOR_1 inline // current ABI revision + + TODO: Auto-generate this based on information in version.cmake +*/ + +#define MYSQLX_ABI_MAJOR_2 inline // current ABI version +#define MYSQLX_ABI_MINOR_0 inline // current ABI revision + + +#define MYSQLX_ABI_BEGIN(X,Y) \ + MYSQLX_ABI_MAJOR_ ## X namespace abi ## X { \ + MYSQLX_ABI_MINOR_ ## Y namespace r ## Y { + +#define MYSQLX_ABI_END(X,Y) }} + +#define MYSQLX_ABI(X,Y) mysqlx::abi##X::r##Y + +#ifdef __cplusplus + +namespace mysqlx { + + +MYSQLX_ABI_BEGIN(2,0) + + namespace internal { + } + + namespace common { + } + +MYSQLX_ABI_END(2,0) + +/* + When new revision 1 of the current ABI 2 is added, the following declarations + should be added. They import all revision 0 symbols into revision 1. Symbols + that have changed should be defined inside + MYSQLX_ABI_BEGIN(2,1) ... MYSQLX_ABI_END(2,1) and they will + shadow the corresponding revision 0 symbol. + + MYSQLX_ABI_BEGIN(2,1) + + using namespace r0; + + namespace internal { + using namespace r0::internal; + } + + namespace common { + using namespace r0::common; + } + + MYSQLX_ABI_END(2,1) +*/ + +} + +#endif // __cplusplus + + +/* + Macros for declaring public API + =============================== + + API function declarations should be decorated with PUBLIC_API prefix. API + classes should have PUBLIC_API marker between the "class" keyword and + the class name. + + See: https://gcc.gnu.org/wiki/Visibility + + TODO: Use better name than PUBLIC_API - not all public API classes should + be decorated with these declarations but only these whose implementation + is inside the library (so, not the ones which are implemented in headers). +*/ + +#if defined _MSC_VER + + #define DLL_EXPORT __declspec(dllexport) + #define DLL_IMPORT __declspec(dllimport) + #define DLL_LOCAL + +#elif __GNUC__ >= 4 + + #define DLL_EXPORT __attribute__ ((visibility ("default"))) + #define DLL_IMPORT + #define DLL_LOCAL __attribute__ ((visibility ("hidden"))) + +#elif defined __SUNPRO_CC || defined __SUNPRO_C + + #define DLL_EXPORT __global + #define DLL_IMPORT __global + #define DLL_LOCAL __hidden + +#else + + #define DLL_EXPORT + #define DLL_IMPORT + #define DLL_LOCAL + +#endif + + +#if defined CONCPP_BUILD_SHARED + #define PUBLIC_API DLL_EXPORT + #define INTERNAL DLL_LOCAL +#elif defined CONCPP_BUILD_STATIC + #define PUBLIC_API + #define INTERNAL +#elif !defined STATIC_CONCPP + #define PUBLIC_API DLL_IMPORT + #define INTERNAL +#else + #define PUBLIC_API + #define INTERNAL +#endif + + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/common/error.h b/Libraries/mysql-connector/include/mysqlx/common/error.h new file mode 100644 index 0000000..9af5753 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/common/error.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef MYSQLX_COMMON_ERROR_H +#define MYSQLX_COMMON_ERROR_H + +/* + TODO: Error handling infrastructure for XDevAPI and X DevAPI for C still + needs to be done. Current code is just a temporary hack. +*/ + +#include "api.h" +#include "util.h" + +PUSH_SYS_WARNINGS +#include +#include +#include +#include +#include +#include // for memcpy +#include // std::move etc +POP_SYS_WARNINGS + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +namespace common { + +/** + Base class for connector errors. + + @internal + TODO: Derive from std::system_error and introduce proper + error codes. + @endinternal + + @ingroup devapi +*/ + +class Error : public std::runtime_error +{ +public: + + Error(const char *msg) + : std::runtime_error(msg) + {} +}; + + +inline +std::ostream& operator<<(std::ostream &out, const Error &e) +{ + out << e.what(); + return out; +} + + +inline +void throw_error(const char *msg) +{ + throw Error(msg); +} + +} // common + +MYSQLX_ABI_END(2,0) +} // mysqlx + + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/common/op_if.h b/Libraries/mysql-connector/include/mysqlx/common/op_if.h new file mode 100644 index 0000000..b17cb7b --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/common/op_if.h @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_COMMON_OP_IF_H +#define MYSQLX_COMMON_OP_IF_H + +/* + This file defines a hierarchy of abstract interfaces for objects that + represent database operations. The base interface is the Executable_if for + any operation that can be executed. Other interfaces in the hierarchy allow + specifying more details of the operation. + + Note: Header op_impl.h defines implementations of these interfaces used + in the connector. +*/ + +#include "api.h" +#include "../common_constants.h" +#include + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) +namespace common { + +class Result_init; +class Value; + +#define LOCK_MODE(X,N) X = N, +enum Lock_mode +{ + LOCK_MODE_LIST(LOCK_MODE) +}; + +#define LOCK_CONTENTION(X,N) X = N, +enum class Lock_contention +{ + LOCK_CONTENTION_LIST(LOCK_CONTENTION) +}; + + +/* + Abstract interface for internal implementations of an executable object. + + The execute() method returns a Result_init object which can be + used to construct a result instance. + + Implementation of an executable object holds a description of the operation + that should be executed. Executable objects can be copied (for example + by copy assignment operation) and in this case a new copy of the current + description of the operation should be created by clone() method. After + cloning, the 2 executable implementations can be modified and executed + independently. + + See various Op_xxx classes defined for example in operation.h to see examples + of executable object implementations. Note that these Op_xxx classes do + not directly inherit from Executable_if. Instead they use a whole hierarchy + of implementation classes based on Executable_if. But in the end, each + implementation of an executable object defines the execute() method that + executes given operation using all the information collected using other + methods of the implementation class. +*/ + +struct Executable_if +{ + /* + Execute the operation and return reference to object which implements + Result_init interface. Such object is then used to construct a result + instance. + */ + + virtual Result_init& execute() = 0; + + virtual Executable_if *clone() const = 0; + + virtual ~Executable_if() {} +}; + + +/* + The XXX_if classes defined below form a hierarchy of interfaces, based + on Executable_if, for internal implementations of various crud operations. + The concrete implementations, like Op_collection_find defined in + operation.h, implements one of the top interfaces in this hierarchy but + the hierarchy allows casting the implementation down to the layer + implementing particular aspect of the operation. For example + Limit_if interface allows setting limit and offset for returned/affected + rows/documents, which is common for different CRUD operations. +*/ + + +struct Bind_if : public Executable_if +{ + using string = std::string; + + // Add value for named parameter + + virtual void add_param(const string&, const Value&) = 0; + + // Add value for positional parameter + + virtual void add_param(Value) = 0; + + virtual void clear_params() = 0; +}; + + +struct Limit_if : public Bind_if +{ + virtual void set_offset(unsigned) = 0; + virtual void clear_offset() = 0; + + virtual void set_limit(unsigned) = 0; + virtual void clear_limit() = 0; +}; + + +struct Sort_if : public Limit_if +{ + using string = std::string; + enum direction_t { ASC, DESC }; + + virtual void add_sort(const string &expr, direction_t dir) = 0; + virtual void add_sort(const string&) = 0; + virtual void clear_sort() = 0; +}; + + +struct Having_if : public Sort_if +{ + using string = std::string; + + virtual void set_having(const string&) = 0; + virtual void clear_having() = 0; +}; + + +struct Group_by_if : public Having_if +{ + using string = std::string; + + virtual void add_group_by(const string&) = 0; + virtual void clear_group_by() = 0; +}; + + +struct Proj_if : public Group_by_if +{ + using string = std::string; + + /* + Add projection specification for a table query. It is an expression with + optional "AS " suffix. + */ + + virtual void add_proj(const string&) = 0; + + /* + Set projection for a document query. It is a JSON-like string but document + field values are interpreted as expressions. + */ + + virtual void set_proj(const string&) = 0; + + virtual void clear_proj() = 0; +}; + + +template +struct Select_if : public Base +{ + using string = std::string; + + // Set expression to select rows/documents. + + virtual void set_where(const string&) = 0; + + // Define lock mode for rows/documents returned by the query. + + virtual void set_lock_mode(Lock_mode, Lock_contention) = 0; + virtual void clear_lock_mode() = 0; +}; + + +// -------------------------------------------------------------------------- + + +struct Collection_find_if : public Select_if +{}; + + +/* + Interface to internal implementations of CRUD add operation. +*/ + +struct Collection_add_if : public Executable_if +{ + /* + Note: Current implementation only supports sending + documents in form of UTF8 JSON strings. + */ + + virtual void add_json(const std::string&) = 0; + virtual void clear_docs() = 0; +}; + + +struct Collection_remove_if : public Select_if +{}; + + +/* + Interface to internal implementations of CRUD modify operation. + + Methods `add_operation` are used to pass to the implementation object + the modifications requested by the user. +*/ + +struct Collection_modify_if : public Select_if +{ + using string = std::string; + + enum Operation + { + SET, + UNSET, + ARRAY_INSERT, + ARRAY_APPEND, + ARRAY_DELETE, + MERGE_PATCH + }; + + virtual void add_operation(Operation, const string&, const Value&) = 0; + virtual void add_operation(Operation, const string&) = 0; + virtual void clear_modifications() = 0; +}; + + +// -------------------------------------------------------------------------- + + +/* + Interface to be implemented by internal implementations of + table insert operation. +*/ + +template +struct Table_insert_if : public Executable_if +{ + using string = std::string; + + /* + Pass to the implementation names of columns specified by + the user. Columns are passed one-by-one in the order in + which they were specified. + */ + + virtual void add_column(const string&) = 0; + virtual void clear_columns() = 0; + + /* + Pass to the implementation a row that should be inserted + into the table. Several rows can be passed. + + TODO: use move semantics instead + */ + + virtual void add_row(const Row_impl&) = 0; + virtual void clear_rows() = 0; +}; + + +/* + Interface to be implemented by internal implementations + of table CRUD select operation. + + Method `add_where` is used to report selection criteria + to the implementation. +*/ + +struct Table_select_if : public Select_if +{}; + + +/* + Interface to be implemented by internal implementations + of table CRUD remove operation. + + Selection criteria which selects rows to be removed is + passed to the implementation using `set_where` method. + + Note: setting where condition to empty string removes it. +*/ + +struct Table_remove_if : public Select_if +{}; + + +/* + Interface to be implemented by internal implementations of + table CRUD update operation. Such update operation sets values + of fields in a row. Name of the column that should be set and + expression defining new value are reported to the implementation + using method `add_set`. +*/ + +struct Table_update_if : public Table_remove_if +{ + using string = std::string; + + virtual void add_set(const string&, const Value&) = 0; + virtual void clear_modifications() = 0; +}; + +} // internal +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/common/settings.h b/Libraries/mysql-connector/include/mysqlx/common/settings.h new file mode 100644 index 0000000..1465a53 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/common/settings.h @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_COMMON_SETTINGS_H +#define MYSQLX_COMMON_SETTINGS_H + +/* + Classes and code handling session settings. They are used to process session + creation options, check their consistency and present the settings in the + form expected by CDK. + + Known session options and their values are defined + in mysql_common_constants.h header as SESSION_OPTION_LIST() and accompanying + macros. +*/ + +#include "../common_constants.h" +#include "value.h" + +PUSH_SYS_WARNINGS +#include +#include +#include +#include +POP_SYS_WARNINGS + + +namespace cdk { +namespace ds { + +class Multi_source; +struct Attr_processor; + +}} + + +namespace mysqlx { + +MYSQLX_ABI_BEGIN(2,0) + +namespace common { + + +/* + Class for storing session configuration settings. +*/ + +class PUBLIC_API Settings_impl +{ +public: + + /* + Enumerations with available session options and their values. + */ + +#define SETTINGS_OPT_ENUM_str(X,N) X = N, +#define SETTINGS_OPT_ENUM_num(X,N) X = N, +#define SETTINGS_OPT_ENUM_any(X,N) X = N, +#define SETTINGS_OPT_ENUM_bool(X,N) X = N, + + enum Session_option_impl{ + SESSION_OPTION_LIST(SETTINGS_OPT_ENUM) + LAST + }; + + + + /* + Enumerations with available client options and their values. + */ + +#define CLIENT_OPT_IMPL_ENUM_str(X,N) X = -N, +#define CLIENT_OPT_IMPL_ENUM_bool(X,N) X = -N, +#define CLIENT_OPT_IMPL_ENUM_num(X,N) X = -N, +#define CLIENT_OPT_IMPL_ENUM_any(X,N) X = -N, + + enum Client_option_impl { + CLIENT_OPTION_LIST(CLIENT_OPT_IMPL_ENUM) + }; + + + + static const char* option_name(int opt); + + +#define SETTINGS_VAL_ENUM(X,N) X = N, + + enum class SSL_mode { + SSL_MODE_LIST(SETTINGS_VAL_ENUM) + LAST + }; + + static const char* ssl_mode_name(SSL_mode mode); + + + enum class Auth_method { + AUTH_METHOD_LIST(SETTINGS_VAL_ENUM) + LAST + }; + + static const char* auth_method_name(Auth_method method); + + enum class Compression_mode { + COMPRESSION_MODE_LIST(SETTINGS_VAL_ENUM) + LAST + }; + + static const char* compression_mode_name(Compression_mode mode); + +protected: + + using Value = common::Value; + using opt_val_t = std::pair; + // TODO: use multimap instead? + using option_list_t = std::vector; + using connection_attr = std::map; + using iterator = option_list_t::const_iterator; + +public: + + /* + Examine settings stored in this object. + */ + + bool has_option(int) const; + const Value& get(int) const; + + + // Iterating over options stored in this object. + + iterator begin() const + { + return m_data.m_options.cbegin(); + } + + iterator end() const + { + return m_data.m_options.cend(); + } + + /* + Clear individual or all settings. + */ + + void clear(); + void erase(int); + + /* + Session options include connection options that specify data source + (one or many) for which given session is created. This method initializes + CDK Multi_source object to describe the data source(s) based on the + connection options. + */ + + void get_data_source(cdk::ds::Multi_source&); + + void get_attributes(cdk::ds::Attr_processor&); + + // Set options based on URI + + void set_from_uri(const std::string &); + + // Set Client options based on JSON object + + void set_client_opts(const std::string &); + + // Set Client options from othe Settings object + + void set_client_opts(const Settings_impl &); + + /* + Public API has no methods to directly set individual options. Instead, + to change session settings implementation should create a Setter object + and use its methods to do the changes. A Settings_impl::Setter object + provides "transactional" semantics for changing session options -- only + consistent option changes modify the original Settings_impl object. + + Note: This Setter class is defined in "implementation" header + common/settings.h. The public API leaves it undefined. + */ + + class Setter; + +protected: + + struct PUBLIC_API Data + { + Data() + { + init_connection_attr(); + } + DLL_WARNINGS_PUSH + option_list_t m_options; + connection_attr m_connection_attr; + DLL_WARNINGS_POP + unsigned m_host_cnt = 0; + bool m_user_priorities = false; + bool m_ssl_ca = false; + SSL_mode m_ssl_mode = SSL_mode::LAST; + bool m_tcpip = false; // set to true if TCPIP connection was specified + bool m_sock = false; // set to true if socket connection was specified + bool m_tls_vers = false; + bool m_tls_ciphers = false; + bool m_compression_algorithms = false; + + void erase(int); + void init_connection_attr(); + void clear_connection_attr(); + + }; + + Data m_data; + +}; + + +#define SETTINGS_OPT_NAME_str(X,N) case N: return #X; +#define SETTINGS_OPT_NAME_bool(X,N) case N: return #X; +#define SETTINGS_OPT_NAME_num(X,N) case N: return #X; +#define SETTINGS_OPT_NAME_any(X,N) case N: return #X; +#define SETTINGS_OPT_NAME_bool(X,N) case N: return #X; + + +#define CLIENT_OPT_NAME_str(X,N) case -N: return #X; +#define CLIENT_OPT_NAME_bool(X,N) case -N: return #X; +#define CLIENT_OPT_NAME_num(X,N) case -N: return #X; +#define CLIENT_OPT_NAME_any(X,N) case -N: return #X; + + +inline +const char* Settings_impl::option_name(int opt) +{ + switch (opt) + { + SESSION_OPTION_LIST(SETTINGS_OPT_NAME) + CLIENT_OPTION_LIST(CLIENT_OPT_NAME) + default: + return nullptr; + } +} + + +#define SETTINGS_VAL_NAME(X,N) case N: return #X; + +inline +const char* Settings_impl::ssl_mode_name(SSL_mode mode) +{ + switch (unsigned(mode)) + { + SSL_MODE_LIST(SETTINGS_VAL_NAME) + default: + return nullptr; + } +} + +inline +const char* Settings_impl::auth_method_name(Auth_method method) +{ + switch (unsigned(method)) + { + AUTH_METHOD_LIST(SETTINGS_VAL_NAME) + default: + return nullptr; + } +} + +inline +const char* Settings_impl::compression_mode_name(Compression_mode mode) +{ + switch (unsigned(mode)) + { + COMPRESSION_MODE_LIST(SETTINGS_VAL_NAME) + default: + return nullptr; + } +} + +/* + Note: For options that can repeat, returns the last value. +*/ + +inline +const common::Value& Settings_impl::get(int opt) const +{ + using std::find_if; + + auto it = find_if(m_data.m_options.crbegin(), m_data.m_options.crend(), + [opt](opt_val_t el) -> bool { return el.first == opt; } + ); + + static Value null_value; + + if (it == m_data.m_options.crend()) + return null_value; + + return it->second; +} + + +inline +bool Settings_impl::has_option(int opt) const +{ + // For options whose value is a list, we return true if we know the option + // was set even if no actual values are stored in m_options, which is the + // case when option value is an empty list. + + switch (opt) + { + case Session_option_impl::TLS_VERSIONS: + if (m_data.m_tls_vers) + return true; + break; + + case Session_option_impl::TLS_CIPHERSUITES: + if (m_data.m_tls_ciphers) + return true; + break; + + case Session_option_impl::COMPRESSION_ALGORITHMS: + if (m_data.m_compression_algorithms) + return true; + break; + + default: + break; + } + + return m_data.m_options.cend() != + find_if(m_data.m_options.cbegin(), m_data.m_options.cend(), + [opt](opt_val_t el) -> bool { return el.first == opt; } + ); + +} + + +inline +void Settings_impl::erase(int opt) +{ + m_data.erase(opt); +} + + +/* + Note: Removes all occurrences of the given option. Also updates the context + used for checking option consistency. +*/ + +inline +void Settings_impl::Data::erase(int opt) +{ + remove_from(m_options, + [opt](opt_val_t el) -> bool + { + return el.first == opt; + } + ); + + /* + TODO: removing HOST from multi-host settings can leave "orphaned" + PORT/PRIORITY settings. Do we correctly detect that? + */ + + switch (opt) + { + case Session_option_impl::HOST: + m_host_cnt = 0; + FALLTHROUGH; + case Session_option_impl::PORT: + if (0 == m_host_cnt) + m_tcpip = false; + break; + case Session_option_impl::SOCKET: + m_sock = false; + break; + case Session_option_impl::PRIORITY: + m_user_priorities = false; + break; + case Session_option_impl::SSL_CA: + m_ssl_ca = false; + break; + case Session_option_impl::SSL_MODE: + m_ssl_mode = SSL_mode::LAST; + break; + case Session_option_impl::CONNECTION_ATTRIBUTES: + clear_connection_attr(); + break; + default: + break; + } +} + + +} // common namespace + +MYSQLX_ABI_END(2,0) + +} // mysqlx namespace + +#endif + diff --git a/Libraries/mysql-connector/include/mysqlx/common/util.h b/Libraries/mysql-connector/include/mysqlx/common/util.h new file mode 100644 index 0000000..a21f692 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/common/util.h @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_COMMON_UTIL_H +#define MYSQLX_COMMON_UTIL_H + +#include "api.h" +#include + +/* + Macros used to disable warnings for fragments of code. +*/ + +#if defined _MSC_VER + + +#define PRAGMA(X) __pragma(X) +#define DISABLE_WARNING(W) PRAGMA(warning (disable:W)) + +#define DIAGNOSTIC_PUSH PRAGMA(warning (push)) +#define DIAGNOSTIC_POP PRAGMA(warning (pop)) + +#elif defined __GNUC__ || defined __clang__ + +#define PRAGMA(X) _Pragma(#X) +#define DISABLE_WARNING(W) PRAGMA(GCC diagnostic ignored #W) + +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) +#define DIAGNOSTIC_PUSH PRAGMA(GCC diagnostic push) +#define DIAGNOSTIC_POP PRAGMA(GCC diagnostic pop) +#else +#define DIAGNOSTIC_PUSH +#define DIAGNOSTIC_POP +#endif + +#else + +#define PRAGMA(X) +#define DISABLE_WARNING(W) + +#define DIAGNOSTIC_PUSH +#define DIAGNOSTIC_POP + +#endif + + +/* + Macros to disable compile warnings in system headers. Put + PUSH_SYS_WARNINGS/POP_SYS_WARNINGS around sytem header includes. +*/ + +#if defined _MSC_VER + +/* + Warning 4350 is triggered by std::shared_ptr<> implementation + - see https://msdn.microsoft.com/en-us/library/0eestyah.aspx + + Warning 4365 conversion from 'type_1' to 'type_2', signed/unsigned mismatch + - see https://msdn.microsoft.com/en-us/library/ms173683.aspx + + Warning 4774 format string expected in argument is not a + string literal +*/ + +#define PUSH_SYS_WARNINGS \ + PRAGMA(warning (push,2)) \ + DISABLE_WARNING(4350) \ + DISABLE_WARNING(4738) \ + DISABLE_WARNING(4548) \ + DISABLE_WARNING(4365) \ + DISABLE_WARNING(4774) \ + DISABLE_WARNING(4244) + +#else + +#define PUSH_SYS_WARNINGS DIAGNOSTIC_PUSH + +#endif + +#define POP_SYS_WARNINGS DIAGNOSTIC_POP + +PUSH_SYS_WARNINGS + +#include +#include +#include +#include +#include +#include // for memcpy +#include // std::move etc +#include +#include +#include + +POP_SYS_WARNINGS + +/* + Macro to be used to disable "implicit fallthrough" gcc warning + +*/ + +#ifndef FALLTHROUGH +# ifdef __GNUC__ +# if __GNUC__ < 7 +# define FALLTHROUGH // fallthrough +# else +# if __cplusplus >= 201703L +# define FALLTHROUGH [[fallthrough]] // C++17 +# elif __cplusplus >= 201103L +# define FALLTHROUGH [[gnu::fallthrough]] // C++11 and C++14 +# else +# define FALLTHROUGH __attribute__((fallthrough)) +# endif +# endif +# else +# define FALLTHROUGH // fallthrough +# endif +#endif //FALLTHROUGH + +/* + Note: we add throw statement to the definition of THROW() so that compiler won't + complain if it is used in contexts where, e.g., a value should be returned from + a function. +*/ + +#undef THROW + +#ifdef THROW_AS_ASSERT + +#define THROW(MSG) do { assert(false && (MSG)); throw (MSG); } while(false) + +#else + +#define THROW(MSG) do { throw_error(MSG); throw (MSG); } while(false) + +#endif + + +/* + Macros used to disable warnings for fragments of code. +*/ + +#undef PRAGMA +#undef DISABLE_WARNING +#undef DIAGNOSTIC_PUSH +#undef DIAGNOSTIC_POP + +#if defined _MSC_VER + +#define PRAGMA(X) __pragma(X) +#define DISABLE_WARNING(W) PRAGMA(warning(disable : W)) + +#define DIAGNOSTIC_PUSH PRAGMA(warning(push)) +#define DIAGNOSTIC_POP PRAGMA(warning(pop)) + +#elif defined __GNUC__ || defined __clang__ + +#define PRAGMA(X) _Pragma(#X) +#define DISABLE_WARNING(W) PRAGMA(GCC diagnostic ignored #W) + +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) +#define DIAGNOSTIC_PUSH PRAGMA(GCC diagnostic push) +#define DIAGNOSTIC_POP PRAGMA(GCC diagnostic pop) +#else +#define DIAGNOSTIC_PUSH +#define DIAGNOSTIC_POP +#endif + +#else + +#define PRAGMA(X) +#define DISABLE_WARNING(W) + +#define DIAGNOSTIC_PUSH +#define DIAGNOSTIC_POP + +#endif + + +/* + On Windows, MSVC issues warnings if public API class definition uses + another class which is not exported as public API (either as a base class + or type of member). This is indeed dangerous because client code might get + the class definition wrong if the non-exported component is not available or + (worse) is defined in a different way than the same component during connector + build time. + + We can not completely avoid these warnings because for some API classes we + use standard C++ library classes as components. For example, we use + std::shared_ptr<> a lot. We can not modify standard library headers to export + these classes. As is the common practice, we ignore this issue assuming that + the code that uses our connector is built with the same C++ runtime + implementation as the one used to build the connector. To silence the warnings, + uses of standard library classes in our public API classes should be surrounded + with DLL_WARNINGS_PUSH/POP macros. +*/ + +#if defined _MSC_VER + +#define DLL_WARNINGS_PUSH DIAGNOSTIC_PUSH \ + DISABLE_WARNING(4251) \ + DISABLE_WARNING(4275) +#define DLL_WARNINGS_POP DIAGNOSTIC_POP + +#else + +#define DLL_WARNINGS_PUSH +#define DLL_WARNINGS_POP + +#endif + + +/* + A dirty trick to help Doxygen to process 'enum class' declarations, which + are not fully supported. Thus we replace them by plain 'enum' when processing + sources by Doxygen. +*/ + +#ifdef DOXYGEN +#define enum_class enum +#else +#define enum_class enum class +#endif + + +/* + Macro to put at the end of other macros that define lists of items. This is + another dirty trick for Doxygen to hide from it a documentation of the last + item in the list. Otherwise, in a situation like this: + + #define ITEM_LIST(X) \ + X(item1) \ + ... + X(itemN) /##< Doc for last item #/ + + Doxegen treats the documentation of the last item as documentation for + the whole ITEM_LIST() macro. This does not happen if END_LIST is added at + the end: + + #define ITEM_LIST(X) \ + X(item1) \ + ... + X(itemN) /##< Doc for last item #/ \ + END_LIST +*/ + +#define END_LIST + + +#ifdef __cplusplus + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +namespace common { + +/* + Convenience for checking numeric limits (to be used when doing numeric + casts). + + TODO: Maybe more templates are needed for the case where T is a float/double + type and U is an integer type or vice versa. +*/ + +template < + typename T, typename U, + typename std::enable_if::value>::type* = nullptr +> +inline +bool check_num_limits(U val) +{ + using UT = typename std::make_unsigned::type; + return !(val > (UT)std::numeric_limits::max()); +} + +template < + typename T, typename U, + typename std::enable_if::value>::type* = nullptr, + typename std::enable_if::value>::type* = nullptr +> +inline +bool check_num_limits(U val) +{ + return !(val < 0) && !(val > std::numeric_limits::max()); +} + +template < + typename T, typename U, + typename std::enable_if::value>::type* = nullptr, + typename std::enable_if::value>::type* = nullptr +> +inline +bool check_num_limits(U val) +{ + return + !((val > std::numeric_limits::max()) + || (val < std::numeric_limits::lowest())); +} + +#define ASSERT_NUM_LIMITS(T,V) assert(::mysqlx::common::check_num_limits(V)) + + + +inline +std::string to_upper(const std::string &val) +{ + using std::transform; + + std::string uc_val; + uc_val.resize(val.size()); + transform(val.begin(), val.end(), uc_val.begin(), ::toupper); + return uc_val; +} + +inline +std::string to_lower(const std::string &val) +{ + using std::transform; + + std::string uc_val; + uc_val.resize(val.size()); + transform(val.begin(), val.end(), uc_val.begin(), ::tolower); + return uc_val; +} + +} // common + + +namespace common { + +#ifdef USE_NATIVE_BYTE + using ::byte; +#else + typedef unsigned char byte; +#endif + + class nocopy + { + public: + nocopy(const nocopy&) = delete; + nocopy& operator=(const nocopy&) = delete; + protected: + nocopy() {} + }; + + + class Printable + { + virtual void print(std::ostream&) const = 0; + friend std::ostream& operator<<(std::ostream&, const Printable&); + }; + + inline + std::ostream& operator<<(std::ostream &out, const Printable &obj) + { + obj.print(out); + return out; + } + + +} // common + + +namespace common { + +using std::find_if; + +/* + Remove from a container all elements that satisfy the given predicate. +*/ + +template +void remove_from(CONT &cont, PRED pred) +{ + using It = typename CONT::iterator; + It end = std::remove_if(cont.begin(), cont.end(), pred); + cont.erase(end, cont.end()); +} + + +} // common +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif // __cplusplus + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/common/value.h b/Libraries/mysql-connector/include/mysqlx/common/value.h new file mode 100644 index 0000000..4f1b7a3 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/common/value.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_COMMON_VALUE_H +#define MYSQLX_COMMON_VALUE_H + + +#include "api.h" +#include "error.h" +#include "util.h" + +PUSH_SYS_WARNINGS +#include +POP_SYS_WARNINGS + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +namespace common { + +class Value_conv; + +/* + Class representing a polymorphic value of one of the supported types. + + TODO: Extend it with array and document types (currently these are implemented + in derived mysqlx::Value class of DevAPI). + + TODO: When storing raw bytes, currently they are copied inside the Value + object. Consider if this can be avoided. +*/ + +class PUBLIC_API Value + : public virtual Printable +{ +public: + + enum Type + { + VNULL, ///< Null value + UINT64, ///< Unsigned integer + INT64, ///< Signed integer + FLOAT, ///< Float number + DOUBLE, ///< Double number + BOOL, ///< Boolean + STRING, ///< String (utf8) + USTRING, ///< Wide string (utf16) + RAW, ///< Raw bytes + EXPR, ///< String to be interpreted as an expression + JSON, ///< JSON string + }; + + using string = std::string; + +protected: + + Type m_type; + + // TODO: Use std::variant to save space + + DLL_WARNINGS_PUSH + + std::string m_str; + std::u16string m_ustr; + + DLL_WARNINGS_POP + + union { + double v_double = 0.0; + float v_float; + int64_t v_sint; + uint64_t v_uint; + bool v_bool; + } m_val; + + void print(std::ostream&) const override; + + template + Value(Type type, T &&init) + : Value(std::forward(init)) + { + m_type = type; + } + +public: + + // Construct a NULL item + Value() : m_type(VNULL) + {} + + + // Construct an item from a string + Value(const std::string& str) : m_type(STRING), m_str(str) + { + m_val.v_bool = false; + } + + Value(const std::u16string &str) + : m_type(USTRING), m_ustr(str) + { + m_val.v_bool = false; + } + + + // Construct an item from a signed 64-bit integer + Value(int64_t v) : m_type(INT64) + { m_val.v_sint = v; } + + // Construct an item from an unsigned 64-bit integer + Value(uint64_t v) : m_type(UINT64) + { m_val.v_uint = v; } + + // Construct an item from a float + Value(float v) : m_type(FLOAT) + { m_val.v_float = v; } + + // Construct an item from a double + Value(double v) : m_type(DOUBLE) + { m_val.v_double = v; } + + + // Construct an item from a bool + Value(bool v) : m_type(BOOL) + { m_val.v_bool = v; } + + // Construct an item from bytes + Value(const byte *ptr, size_t len) : m_type(RAW) + { + // Note: bytes are copied to m_str member. + m_str.assign((const char*)ptr, len); + } + + // Other numeric conversions + + template < + typename T, + typename std::enable_if::value>::type* = nullptr + > + Value(T val) + : Value(uint64_t(val)) + {} + + template < + typename T, + typename std::enable_if::value>::type* = nullptr, + typename std::enable_if::value>::type* = nullptr + > + Value(T val) + : Value(int64_t(val)) + {} + + + bool is_null() const + { + return VNULL == m_type; + } + + bool get_bool() const + { + switch (m_type) + { + case BOOL: return m_val.v_bool; + case UINT64: return 0 != m_val.v_uint; + case INT64: return 0 != m_val.v_sint; + default: + throw Error("Can not convert to Boolean value"); + } + } + + uint64_t get_uint() const + { + if (UINT64 != m_type && INT64 != m_type && BOOL != m_type) + throw Error("Can not convert to integer value"); + + if (BOOL == m_type) + return m_val.v_bool ? 1 : 0; + + if (INT64 == m_type && 0 > m_val.v_sint) + throw Error("Converting negative integer to unsigned value"); + + uint64_t val = (UINT64 == m_type ? m_val.v_uint : (uint64_t)m_val.v_sint); + + return val; + } + + int64_t get_sint() const + { + if (INT64 == m_type) + return m_val.v_sint; + + uint64_t val = get_uint(); + + if (!check_num_limits(val)) + throw Error("Value cannot be converted to signed integer number"); + + return val; + } + + float get_float() const + { + switch (m_type) + { + case INT64: return 1.0F*m_val.v_sint; + case UINT64: return 1.0F*m_val.v_uint; + case FLOAT: return m_val.v_float; + default: + throw Error("Value cannot be converted to float number"); + } + } + + double get_double() const + { + switch (m_type) + { + case INT64: return 1.0*m_val.v_sint; + case UINT64: return 1.0*m_val.v_uint; + case FLOAT: return m_val.v_float; + case DOUBLE: return m_val.v_double; + default: + throw Error("Value can not be converted to double number"); + } + } + + /* + Note: In general this method returns raw value representation as obtained + from the server, which is stored in m_str member. If a non-string value was + not obtained from the server, there is no raw representation for it and + error is thrown. String values always have raw representation which is + either utf8 or utf16 encoding. Strings obtained from the server use utf8 as + raw representation. For strings created by user code this might be either + utf8 or utf16, depending on how string was created. + */ + + const byte* get_bytes(size_t *size) const + { + switch (m_type) + { + case USTRING: + if (!m_ustr.empty()) + { + if (size) + *size = m_ustr.size() * sizeof(char16_t); + return (const byte*)m_ustr.data(); + } + FALLTHROUGH; + + default: + if (m_str.empty()) + throw Error("Value cannot be converted to raw bytes"); + FALLTHROUGH; + + case RAW: + case STRING: + if (size) + *size = m_str.length(); + return (const byte*)m_str.data(); + + } + } + + // Note: these methods perform utf8 conversions as necessary. + + const std::string& get_string() const; + const std::u16string& get_ustring() const; + + Type get_type() const + { + return m_type; + } + +private: + + /* + Note: Avoid implicit conversion from pointer types to bool. + Without this declaration, Value(bool) constructor is invoked + for pointer types. Here we declare and hide an explicit constructor + for pointer types which prevents compiler to pick Value(bool). + */ + + template + Value(const T*); + +public: + + friend Value_conv; + + struct Access; + friend Access; +}; + +} // common +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/common_constants.h b/Libraries/mysql-connector/include/mysqlx/common_constants.h new file mode 100644 index 0000000..1ae1c48 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/common_constants.h @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQL_COMMON_CONSTANTS_H +#define MYSQL_COMMON_CONSTANTS_H + +#include "version_info.h" + +#define DEFAULT_MYSQL_PORT 3306 +#define DEFAULT_MYSQLX_PORT 33060 + +// ---------------------------------------------------------------------------- + +/* + Common constants + ================ + + Warning: Values of these constants are part of the public API. Changing them + is a non backward compatible API change. + + Note: Value of 0 is reserved for special uses and thus constant values + are always > 0. + + Note: the empty END_LIST macro at the end of list macros helps Doxygen + correctly interpret documentation for the list item. +*/ + +#define OPT_STR(X,Y,N) X##_str(Y,N) +#define OPT_BOOL(X,Y,N) X##_bool(Y,N) +#define OPT_NUM(X,Y,N) X##_num(Y,N) +#define OPT_ANY(X,Y,N) X##_any(Y,N) + + +#undef END_LIST +#define END_LIST + + +#define CLIENT_OPTION_LIST(x) \ + OPT_BOOL(x,POOLING,1) /*!< disable/enable the pool. (Enabled by default)*/ \ + OPT_NUM(x,POOL_MAX_SIZE,2) /*!< size of the pool. (Defaults to 25)*/ \ + OPT_NUM(x,POOL_QUEUE_TIMEOUT,3) /*!< timeout for waiting for a connection in + the pool (ms). (No timeout by default)*/ \ + OPT_NUM(x,POOL_MAX_IDLE_TIME,4)/*!< time for a connection to be in the pool + without being used (ms).(Will not expire by default)*/ \ + END_LIST + + +#define SESSION_OPTION_LIST(x) \ + OPT_STR(x,URI,1) /*!< connection URI or string */ \ + /*! DNS name of the host, IPv4 address or IPv6 address */ \ + OPT_STR(x,HOST,2) \ + OPT_NUM(x,PORT,3) /*!< X Plugin port to connect to */ \ + /*! + Assign a priority (a number in range 1 to 100) to the last specified + host; these priorities are used to determine the order in which multiple + hosts are tried by the connection fail-over logic (see description + of `Session` class) + */ \ + OPT_NUM(x,PRIORITY,4) \ + OPT_STR(x,USER,5) /*!< user name */ \ + OPT_STR(x,PWD,6) /*!< password */ \ + OPT_STR(x,DB,7) /*!< default database */ \ + /*! + Specify \ref SSLMode option to be used. In plain C code the value + should be a `#mysqlx_ssl_mode_t` enum constant. + */ \ + OPT_ANY(x,SSL_MODE,8) \ + /*! path to a PEM file specifying trusted root certificates*/ \ + OPT_STR(x,SSL_CA,9) \ + /*! + Authentication method to use, see \ref AuthMethod. In plain C code the value + should be a `#mysqlx_auth_method_t` enum constant. + */ \ + OPT_ANY(x,AUTH,10) \ + OPT_STR(x,SOCKET,11) /*!< unix socket path */ \ + /*! + Sets connection timeout in milliseconds. In C++ code can be also set to + a `std::chrono::duration` value. + */ \ + OPT_NUM(x,CONNECT_TIMEOUT,12) \ + /*! + Specifies connection attributes (key-value pairs) to be sent when a session + is created. The value is a JSON string (in C++ code can be also a `DbDoc` + object) defining additional attributes to be sent on top of the default + ones. Setting this option to `false` (in C++ code) or NULL (in plain C code) + disables sending any connection attributes (including the default ones). + Setting it to `true` (in C++ code) or empty string (in plain C code) + requests sending only the default attributes which is also the default + behavior when this option is not set. + */ \ + OPT_STR(x,CONNECTION_ATTRIBUTES,13) \ + /*! + List of allowed TLS protocol versions, such as "TLSv1.2". The value is a + string with comma separated versions. In C++ code it can also be an + iterable container with versions. + */ \ + OPT_STR(x,TLS_VERSIONS, 14) \ + /*! + List of allowed TLS cipher suites. The value is a string with + comma separated IANA cipher suitenames (such as + "TLS_RSA_WITH_3DES_EDE_CBC_SHA"). In C++ code it can also be an iterable + container with names. + Unknown cipher suites are silently ignored. + */ \ + OPT_STR(x,TLS_CIPHERSUITES, 15) \ + /*! + If enabled (true) will check hostname for DNS SRV record and use its + configuration (hostname, port, priority and weight) to connect. + */ \ + OPT_BOOL(x, DNS_SRV, 16) \ + OPT_ANY(x,COMPRESSION,17) /*!< enable or disable compression */ \ + /*! + Specify compression algorithms in order of preference + */ \ + OPT_STR(x,COMPRESSION_ALGORITHMS,18) \ + /*! + Path to a directory containing PEM files specifying trusted root + certificates. + */ \ + OPT_STR(x,SSL_CAPATH,19) \ + /*! Path to a PEM file containing certificate revocation lists*/ \ + OPT_STR(x,SSL_CRL,20) \ + /*! + Path to a directory containing PEM files with certificate revocation + lists + */ \ + OPT_STR(x,SSL_CRLPATH,21) \ + END_LIST + + +/* + Names for options supported in the query part of a connection string and + how they map to session options above. + + Note: when adding new options to this list, also update doxygen docs + for mysqlx::SessionSettings URL ctor (include\mysqlx\devapi\settings.h) and + for mysqlx_get_session_from_url() (include\mysqlx\xapi.h). +*/ + +#define URI_OPTION_LIST(X) \ + X("ssl-mode", SSL_MODE) \ + X("ssl-ca", SSL_CA) \ + X("ssl-capath", SSL_CAPATH) \ + X("ssl-crl", SSL_CRL) \ + X("ssl-crlpath", SSL_CRLPATH) \ + X("auth", AUTH) \ + X("connect-timeout", CONNECT_TIMEOUT) \ + X("connection-attributes",CONNECTION_ATTRIBUTES)\ + X("tls-version", TLS_VERSIONS) \ + X("tls-versions", TLS_VERSIONS) \ + X("tls-ciphersuites", TLS_CIPHERSUITES) \ + X("compression", COMPRESSION) \ + X("compression-algorithms", COMPRESSION_ALGORITHMS) \ + END_LIST + + +#define SSL_MODE_LIST(x) \ + x(DISABLED,1) /*!< Establish an unencrypted connection. */ \ + x(REQUIRED,2) /*!< Establish a secure connection if the server supports + secure connections. The connection attempt fails if a + secure connection cannot be established. This is the + default if `SSL_MODE` is not specified. */ \ + x(VERIFY_CA,3) /*!< Like `REQUIRED`, but additionally verify the server + TLS certificate against the configured Certificate + Authority (CA) certificates (defined by `SSL_CA` + Option). The connection attempt fails if no valid + matching CA certificates are found.*/ \ + x(VERIFY_IDENTITY,4) /*!< Like `VERIFY_CA`, but additionally verify that the + server certificate matches the host to which the + connection is attempted.*/\ + END_LIST + + +#define AUTH_METHOD_LIST(x)\ + x(PLAIN,1) /*!< Plain text authentication method. The password is + sent as a clear text. This method is used by + default in encrypted connections. */ \ + x(MYSQL41,2) /*!< Authentication method supported by MySQL 4.1 and newer. + The password is hashed before being sent to the server. + This authentication method works over unencrypted + connections */ \ + x(EXTERNAL,3) /*!< External authentication when the server establishes + the user authenticity by other means such as SSL/x509 + certificates. Currently not supported by X Plugin */ \ + x(SHA256_MEMORY,4) /*!< Authentication using SHA256 password hashes stored in + server-side cache. This authentication method works + over unencrypted connections. + */ \ + END_LIST + +/* + Types that can be reported by MySQL server. +*/ + +#define RESULT_TYPE_LIST(X) \ + X(BIT, 1) \ + X(TINYINT, 2) \ + X(SMALLINT, 3) \ + X(MEDIUMINT, 4) \ + X(INT, 5) \ + X(BIGINT, 6) \ + X(FLOAT, 7) \ + X(DECIMAL, 8) \ + X(DOUBLE, 9) \ + X(JSON, 10) \ + X(STRING, 11) \ + X(BYTES, 12) \ + X(TIME, 13) \ + X(DATE, 14) \ + X(DATETIME, 15) \ + X(TIMESTAMP, 16) \ + X(SET, 17) \ + X(ENUM, 18) \ + X(GEOMETRY, 19) \ + END_LIST + + +/* + Check options for an updatable view. + @see https://dev.mysql.com/doc/refman/en/view-check-option.html +*/ + +#define VIEW_CHECK_OPTION_LIST(x) \ + x(CASCADED,1) \ + x(LOCAL,2) \ + END_LIST + +/* + Algorithms used to process views. + @see https://dev.mysql.com/doc/refman/en/view-algorithms.html +*/ + +#define VIEW_ALGORITHM_LIST(x) \ + x(UNDEFINED,1) \ + x(MERGE,2) \ + x(TEMPTABLE,3) \ + END_LIST + +/* + View security settings. + @see https://dev.mysql.com/doc/refman/en/stored-programs-security.html +*/ + +#define VIEW_SECURITY_LIST(x) \ + x(DEFINER,1) \ + x(INVOKER,2) \ + END_LIST + + +#define LOCK_MODE_LIST(X) \ + X(SHARED,1) /*!< Sets a shared mode lock on any rows that + are read. Other sessions can read the rows, + but cannot modify them until your transaction + commits. If any of these rows were changed by + another transaction that has not yet committed, + your query waits until that transaction ends + and then uses the latest values. */ \ + X(EXCLUSIVE,2) /*!< For index records the search encounters, + locks the rows and any associated index entries, the same + as if you issued an UPDATE statement for those rows. Other + transactions are blocked from updating those rows, + from doing locking in LOCK_SHARED, or from reading + the data in certain transaction isolation levels. */ \ + END_LIST + +#define LOCK_CONTENTION_LIST(X) \ + X(DEFAULT,0) /*!< Block query until existing row locks are released. */ \ + X(NOWAIT,1) /*!< Return error if lock could not be obtained immediately. */ \ + X(SKIP_LOCKED,2) /*!< Execute query immediately, excluding items that are + locked from the query results. */ \ + END_LIST + +#define COMPRESSION_MODE_LIST(x) \ + x(DISABLED,1) /*!< Disables the compression. */ \ + x(PREFERRED,2) /*!< Request compression, but not return error + if compression is requested, but could not be + used */ \ + x(REQUIRED,3) /*!< Request compression and return error if + compression is not supported by the server */ \ + END_LIST + +// ---------------------------------------------------------------------------- + + +#define COLLECTION_OPTIONS_OPTION(X)\ + X(REUSE,1) /*!< Use existing collection. Expects a boolean value. */ \ + X(VALIDATION,2) /*!< Collection validation options. Expects + CollectionValidation or a json string.*/ \ + END_LIST + +#define COLLECTION_VALIDATION_OPTION(X)\ + X(SCHEMA,1) /*!< Collection validation schema, as defined by + https://dev.mysql.com/doc/refman/8.0/en/json-validation-functions.html#function_json-schema-valid + */ \ + X(LEVEL,2) /*!< Defines level of validation on the collection, see + \ref CollectionValidation_Level "CollectionValidation::Level". + In plain C code the value should be + \ref opt_collection_validation_level "mysqlx_collection_validation_level_t". + */ \ + END_LIST + + + // Schema Validation Level + +//Windows defines STRICT as a macro... undefine it +#ifdef STRICT + #undef STRICT +#endif + +#define COLLECTION_VALIDATION_LEVEL(X)\ + X(OFF,1) /*!< No validation will be done on the collection. */ \ + X(STRICT,2) /*!< All collection documents have to comply to validation schema. + */ \ + END_LIST + + + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/collations.h b/Libraries/mysql-connector/include/mysqlx/devapi/collations.h new file mode 100644 index 0000000..c0d2c24 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/collations.h @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_COLLATIONS_H +#define MYSQLX_COLLATIONS_H + +#include "common.h" + +/* + Import Lists of built-in character sets and collations supported by MySQL + Server. +*/ + +#include "mysql_charsets.h" +#include "mysql_collations.h" + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +/* + Enumeration of known character sets. For each character set CS listed + in CDK_CS_LIST() macro, there is CharacterSet::CS constant in this + enumeration. +*/ + + +enum class CharacterSet : unsigned short +{ + #undef CS + #define CS_ENUM(CS) CS, + CDK_CS_LIST(CS_ENUM) +}; + + +#define CS_NAME_SWITCH(CS) case CharacterSet::CS: return #CS; + +/** + Returns name of a character set given by its id. + + @ingroup devapi_res +*/ + +inline +const char* characterSetName(CharacterSet id) +{ + switch (id) + { + CDK_CS_LIST(CS_NAME_SWITCH) + default: + THROW("Unknown character set id"); + } +} + + +/** + Structure that provides information about character set collation. + + For each known collation COLL over character set CS, there is static object + `Collation::%COLL` of type `CollationInfo` which describes + collation COLL. For example `Collation::%swedish_ci` is + an `CollationInfo` object which describes the `swedish_ci` collation over + `latin1` character set. + + @ingroup devapi_res +*/ + +struct CollationInfo +{ + /// Numeric collation id, as used by MySQL server. + + unsigned id() const { return m_id; } + + /// String name of a collation, such as "latin1_generic_ci". + + const char *getName() const { return m_name; } + + /// Id of the character set of this collation. + + CharacterSet getCharacterSet() const { return m_cs; } + + /** + Returns true if given collation is case sensitive. Binary + collations are assumed to be case sensitive. + */ + + bool isCaseSensitive() const { return m_case != case_ci; } + + /// Returns true if this is binary collation. + + bool isBinary() const { return m_case == case_bin; } + + + bool operator==(const CollationInfo &other) const + { + return m_id == other.m_id; + } + + bool operator!=(const CollationInfo &other) const + { + return !operator==(other); + } + +private: + + enum coll_case { case_bin, case_ci, case_cs }; + + CharacterSet m_cs; + unsigned m_id; + coll_case m_case; + const char *m_name; + +public: + + struct Access; + friend Access; +}; + + +template struct Collation; + + +/* + The Collation::COLL constants are generated from information provided by + COLLATION_XXX() macros.Each line X(CS, ID, COLL, CASE) in the expansion of + a COLLATION_XXX() macro declares collation with name COLL for character set + CS. ID is the MySQL id number for the collation. CASE is one of ci, cs or bin + and indicates whether it is case insensitive, sensitive or binary collation, + respectively. +*/ + +/* + Generate declarations of Collation::COLL constants using + COLLATINS_XXX() macros. The list CS_LIST() is processed using + COLL_DECL() macro, which for each character set CS declares + specialization Collation of the Collation<> template and + declares collation constants within this specialization. + + The collation constant declarations are generated by processing + COLLATIONS_CS() list with COLL_CONST() macro. The name of each + constant is generated by COLL_CONST_NAME() macro. The convention + used is that case insensitive and case sensitive collations get + a _ci or _cs suffix, respectively, while binary collation constant + have no suffix to the collation name. + + Collation constants declared here are defined in file result.cc. +*/ + +#define COLL_DECL(CS) \ +template<> struct Collation \ +{ COLLATIONS_##CS(COLL_CONST) }; \ + +#define COLL_CONST(CS,ID,COLL,CASE) \ +static PUBLIC_API const CollationInfo COLL_CONST_NAME(COLL,CASE); + +#define COLL_CONST_NAME(COLL,CASE) COLL_CONST_NAME_##CASE(COLL) + +#define COLL_CONST_NAME_bin(COLL) COLL +#define COLL_CONST_NAME_ci(COLL) COLL##_ci +#define COLL_CONST_NAME_ai_ci(COLL) COLL##_ai_ci +#define COLL_CONST_NAME_cs(COLL) COLL##_cs +#define COLL_CONST_NAME_as_cs(COLL) COLL##_as_cs +#define COLL_CONST_NAME_as_ci(COLL) COLL##_as_ci +#define COLL_CONST_NAME_as_cs_ks(COLL) COLL##_as_cs_ks + +// Add utf8mb4 alias for bin collation for compatibility + +#undef COLLATIONS_utf8mb4_EXTRA +#define COLLATIONS_utf8mb4_EXTRA \ +static PUBLIC_API const CollationInfo utf8mb4; + +CDK_CS_LIST(COLL_DECL) + +#undef COLLATIONS_utf8mb4_EXTRA +#define COLLATIONS_utf8mb4_EXTRA + + +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/collection_crud.h b/Libraries/mysql-connector/include/mysqlx/devapi/collection_crud.h new file mode 100644 index 0000000..e550e59 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/collection_crud.h @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef MYSQLX_COLLECTION_CRUD_H +#define MYSQLX_COLLECTION_CRUD_H + +/** + @file + Declarations for CRUD operations on document collections. + + Classes declared here represent CRUD operations on a document + collection. An Object of a class such as CollectionAdd represents + a "yet-to-be-executed" operation and stores all the parameters of the + operation. The operation is sent to server for execution only when + `execute()` method is called. + + The following classes for collection CRUD operations are defined: + - CollectionAdd + - CollectionRemove + - CollectionFind + - CollectionModify + + CRUD operation objects can be created directly, or assigned from + result of DevAPI methods that create such operations: + ~~~~~~ + CollectionAdd add_op(coll); + CollectionFind find_op = coll.find(...).sort(...); + ~~~~~~ + + CRUD operation objects have methods which can modify the operation + before it gets executed. For example `CollectionAdd::add()` + appends a document to the list of documents that should be added + by the given CollectionAdd operation. These methods can be chained + as allowed by the fluent API grammar. + + @internal + + The order of fluent API calls is expressed by base classes, such as + Collection_find_base, which are composed from CRUD templates defined + in crud.h. The order of templates determines the allowed order of fluent + API calls. +*/ + + +#include "common.h" +#include "result.h" +#include "executable.h" +#include "crud.h" + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +class Session; +class Collection; +class Table; + +template<> +PUBLIC_API common::Value Value::get() const; + +// ---------------------------------------------------------------------- + +/* + Adding documents to a collection + ================================ +*/ + +class CollectionAdd; + +namespace internal { + +/* + Note: using empty class instead of alias/typedef to help Doxygen correctly + expand templates. +*/ + +struct Collection_add_base + : public Executable +{}; + +} + + +/** + An operation which adds documents to a collection. + + Documents to be added by this operation are specified with various variants + of `add()` method. + + Each document must have a unique identifier which is stored in `_id` + field of the document. Document identifiers are character strings no longer + than 32 characters. If added document does not have `_id` field, a unique + identifier is generated for it. Document identifier generated by a given + collection add operation can be examined using `Result::getDocumentIds()` + method. Generated document identifiers are strings of 32 hexadecimal digits, + like this one `0512020981044082E6119DFA0E4C0584`. + + @note Generated document identifiers are based on UUIDs but they are not + valid UUIDs (fields are reversed). + + @ingroup devapi_op + + @internal + The various `add()` methods are implemented in terms of `do_add()` method + defined by Collection_add_detail class. This method passes documents to + the internal implementation object. +*/ + +class CollectionAdd + : public internal::Collection_add_base + , internal::Collection_add_detail +{ +public: + + /** + Create an empty add operation for the given collection. + */ + + CollectionAdd(Collection &coll) + { + try { + reset(internal::Crud_factory::mk_add(coll)); + } + CATCH_AND_WRAP + } + + CollectionAdd(const internal::Collection_add_base &other) + { + internal::Collection_add_base::operator=(other); + } + + CollectionAdd(internal::Collection_add_base &&other) + { + internal::Collection_add_base::operator=(std::move(other)); + } + + using internal::Collection_add_base::operator=; + + + /** + Add all documents from a range defined by two iterators. + */ + + template + CollectionAdd& add(const It &begin, const It &end) + { + try { + do_add(get_impl(), begin, end); + return *this; + } + CATCH_AND_WRAP + } + + /** + Add all documents within given container. + + Any container type for which `std::begin()`/`std::end()` are defined + should work. + */ + + template + CollectionAdd& add(const Container &c) + { + try { + do_add(get_impl(), c); + return *this; + } + CATCH_AND_WRAP + } + + /** + Add document(s) to a collection. + + Documents can be described by JSON strings or DbDoc objects. + */ + + template + CollectionAdd& add(const Types&... docs) + { + try { + do_add(get_impl(), docs...); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Collection_add_if; + + Impl* get_impl() + { + return static_cast(internal::Collection_add_base::get_impl()); + } + +}; + + +// ---------------------------------------------------------------------- + + +/* + Removing documents from a collection + ==================================== +*/ + +class CollectionRemove; + +namespace internal { + +struct Collection_remove_cmd + : public Executable +{}; + +struct Collection_remove_base + : public Sort< Limit< Bind_parameters< Collection_remove_cmd > > > +{}; + +} // internal namespace + + +/** + An operation which removes documents from a collection. + + @ingroup devapi_op + + @internal + Note: All methods that modify remove operation are defined by the base + class. +*/ + +class CollectionRemove + : public internal::Collection_remove_base +{ + +public: + + /** + Create an operation which removes selected documnets from the given + collection. + + Documents to be removed are specified by the given Boolean expression. + */ + + CollectionRemove(Collection &coll, const string &expr) + { + try { + reset(internal::Crud_factory::mk_remove(coll, expr)); + } + CATCH_AND_WRAP + } + + + CollectionRemove(const internal::Collection_remove_cmd &other) + { + internal::Collection_remove_cmd::operator=(other); + } + + CollectionRemove(internal::Collection_remove_cmd &&other) + { + internal::Collection_remove_cmd::operator=(std::move(other)); + } + + using internal::Collection_remove_cmd::operator=; + +}; + + +// ---------------------------------------------------------------------- + +/* + Searching for documents in a collection + ======================================= +*/ + +class CollectionFind; + +namespace internal { + +struct Collection_find_cmd + : public Executable +{}; + +struct Collection_find_base + : public Group_by< Having< Sort< Limit< Offset< Bind_parameters< + Set_lock< Collection_find_cmd, common::Collection_find_if > + > > > > > > +{}; + +} // internal namespace + + +/** + An operation which returns all or selected documents from a collection. + + @ingroup devapi_op +*/ + +class CollectionFind + : public internal::Collection_find_base + , internal::Collection_find_detail +{ + + using Operation = internal::Collection_find_base; + +public: + + /** + Create an operation which returns all documents from the given collection. + */ + + CollectionFind(Collection &coll) + { + try { + reset(internal::Crud_factory::mk_find(coll)); + } + CATCH_AND_WRAP + } + + /** + Create an operation which returns selected documents from the given + collection. + + Documents to be returned are specified by the given Boolean expression. + */ + + CollectionFind(Collection &coll, const string &expr) + { + try { + reset(internal::Crud_factory::mk_find(coll, expr)); + } + CATCH_AND_WRAP + } + + + CollectionFind(const internal::Collection_find_cmd &other) + { + internal::Collection_find_cmd::operator=(other); + } + + CollectionFind(internal::Collection_find_cmd &&other) + { + internal::Collection_find_cmd::operator=(std::move(other)); + } + + using internal::Collection_find_cmd::operator=; + + +public: + + /** + Specify a projection for the documents returned by this operation. + + Projection is either a single document expression given by `expr()` + or a list (or collection) of strings of the form + `" AS "`. In the latter case each `` + is evaluated and `` specifies where to put the value of + the expression in the resulting document (see `CollectionModify` for more + information about document paths). + */ + + template + Operation& fields(Expr... proj) + { + try { + get_impl()->clear_proj(); + do_fields(get_impl(), proj...); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Collection_find_if; + + Impl* get_impl() + { + return static_cast(internal::Collection_find_base::get_impl()); + } + +}; + + +// ---------------------------------------------------------------------- + +/* + Modifying documents in a collection + =================================== +*/ + +class CollectionModify; + + +namespace internal { + +class CollectionReplace; + +struct Collection_modify_cmd + : public Executable +{}; + +struct Collection_modify_base + : public Sort< Limit< Bind_parameters< Collection_modify_cmd > > > +{}; + +} // internal namespace + + +/** + An operation which modifies all or selected documents in a collection. + + Note that in operations such as `set()`, `unset()`, `arrayInsert()` and + `arrayAppend()` the field argument is specified as a document path. It can be + a simple field name, but it can be a more complex expression like + `$.foo.bar[3]`. One consequence of this is that document field names that + contain spaces or other special characters need to be quoted, for example one + needs to use this form + ``` + .unset("\"field name with spaces\"") + ``` + as `.unset("field name with spaces")` would be an invalid document path + expression. + + Note also that wildcard paths that use `*` or `**` are not valid for these + operations that modify documents. + + See [MySQL Reference Manual](https://dev.mysql.com/doc/refman/en/json.html#json-path-syntax) + for more information on document path syntax supported by MySQL server. + + @ingroup devapi_op +*/ + +class CollectionModify + : public internal::Collection_modify_base +{ + +public: + + /** + Create an operation which modifies selected documents in the given + collection. + + Documents to be modified are specified by the given Boolean expression. + */ + + CollectionModify(Collection &coll, const string &expr) + { + try { + reset(internal::Crud_factory::mk_modify(coll, expr)); + } + CATCH_AND_WRAP + } + + + CollectionModify(const internal::Collection_modify_cmd &other) + { + internal::Collection_modify_cmd::operator=(other); + } + + CollectionModify(internal::Collection_modify_cmd &&other) + { + internal::Collection_modify_cmd::operator=(std::move(other)); + } + + using internal::Collection_modify_cmd::operator=; + + /** + Set the given field in a document to the given value. + + The field is given by a document path. The value can be either a direct + literal, `DbDoc` instance or an expression given as `expr()`, to be + evaluated on the server. + */ + + CollectionModify& set(const Field &field, const Value &val) + { + try { + get_impl()->add_operation(Impl::SET, field, + val.get()); + return *this; + } + CATCH_AND_WRAP + } + + /** + Remove the given field from a document. + + The field is given by a document path. + */ + + CollectionModify& unset(const Field &field) + { + try { + get_impl()->add_operation(Impl::UNSET, field); + return *this; + } + CATCH_AND_WRAP + } + + /** + Insert a value into an array field of a document. + + The `field` parameter should be a document path pointing at a location + inside an array field. The given value is inserted at this position. + */ + + CollectionModify& arrayInsert(const Field &field, const Value &val) + { + try { + get_impl()->add_operation(Impl::ARRAY_INSERT, field, + val.get()); + return *this; + } + CATCH_AND_WRAP + } + + /** + Append a value to an array field of a document. + + The `field` parameter should be a document path pointing at an array + field inside the document. The given value is appended at the end of the + array. + */ + + CollectionModify& arrayAppend(const Field &field, const Value &val) + { + try { + get_impl()->add_operation(Impl::ARRAY_APPEND, field, + val.get()); + return *this; + } + CATCH_AND_WRAP + } + + /** + Apply JSON Patch to a target JSON document. + + The JSON Patch format is defined by + RFC7386. + + A document patch is similar to a JSON object, with the key difference that + document field values can be nested expressions in addition to literal + values. + + The patch contains instructions of how the source document is to be modified + producing a derived document. By default, all fields from the source + document are copied to the resulting document. If patch sets a field to NULL, + the field of that name in the source is skipped from the result, identifiers + and function calls are evaluated against the original source document. + + */ + + CollectionModify& patch(const string &val) + { + try { + get_impl()->add_operation( + Impl::MERGE_PATCH, "$", (const common::Value&)expr(val) + ); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Collection_modify_if; + + Impl* get_impl() + { + return static_cast(internal::Collection_modify_base::get_impl()); + } + +}; + +MYSQLX_ABI_END(2,0) +} // mysqlx namespace + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/common.h b/Libraries/mysql-connector/include/mysqlx/devapi/common.h new file mode 100644 index 0000000..3d8c889 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/common.h @@ -0,0 +1,879 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_COMMON_H +#define MYSQLX_COMMON_H + + +#include "../common.h" + +PUSH_SYS_WARNINGS +#include +#include +#include +#include +#include +#include // for memcpy +#include // std::move etc +POP_SYS_WARNINGS + + +#define CATCH_AND_WRAP \ + catch (const ::mysqlx::Error&) { throw; } \ + catch (const std::out_of_range&) { throw; } \ + catch (const std::exception &e) \ + { throw ::mysqlx::Error(e.what()); } \ + catch (const char *e) \ + { throw ::mysqlx::Error(e); } \ + catch (...) \ + { throw ::mysqlx::Error("Unknown exception"); } \ + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +using std::out_of_range; + +using common::byte; +class Value; + + +/** + Base class for connector errors. + + @internal + TODO: Derive from std::system_error and introduce proper + error codes. + @endinternal + + @ingroup devapi +*/ + +// TODO: Make it header-only class somehow... + +DLL_WARNINGS_PUSH + +class PUBLIC_API Error : public common::Error +{ + + DLL_WARNINGS_POP + +public: + + Error(const char *msg) + : common::Error(msg) + {} +}; + + +inline +void throw_error(const char *msg) +{ + throw Error(msg); +} + + +/** + A wrapper around std::wstring that can perform + conversions from/to different character encodings + used by MySQL. + + Currently only utf-8 encoding is supported. + + @ingroup devapi_aux +*/ + +class string : public std::u16string +{ + + struct Impl + { + PUBLIC_API static std::string to_utf8(const string&); + PUBLIC_API static void from_utf8(string&, const std::string&); + + PUBLIC_API static std::u32string to_ucs4(const string&); + PUBLIC_API static void from_ucs4(string&, const std::u32string&); + + PUBLIC_API static std::wstring to_wide(const string&); + PUBLIC_API static void from_wide(string&, const std::wstring&); + }; + + template + struct traits + {}; + + +public: + + string() {} + string(const string&) = default; + string(string&&) = default; + + string& operator=(const string&) = default; + string& operator=(string&&) = default; + + using std::u16string::basic_string; + + string(const std::u16string &other) : std::u16string(other) {} + string(std::u16string &&other) : std::u16string(std::move(other)) {} + + template + string(const C *other) + { + try { + if (!other) + return; + std::basic_string str(other); + traits::from_str(*this, str); + } + CATCH_AND_WRAP + } + + template + string(const std::basic_string &other) + { + try { + traits::from_str(*this, other); + } + CATCH_AND_WRAP + } + + template + operator std::basic_string() const + { + try { + return traits::to_str(*this); + } + CATCH_AND_WRAP + } + + + friend bool operator==(const string&lhs, const string&rhs) + { + return operator==((const std::u16string&)lhs, (const std::u16string&)rhs); + } + + friend bool operator!=(const string&lhs, const string&rhs) + { + return !(lhs == rhs); + } + + // Note: These are needed to help overload resolution :/ + + friend bool operator==(const string &lhs, const char16_t *rhs) + { + return lhs == string(rhs); + } + + friend bool operator==(const char16_t *lhs, const string &rhs) + { + return string(lhs) == rhs; + } + + friend bool operator!=(const string &lhs, const char16_t *rhs) + { + return !(lhs == rhs); + } + + friend bool operator!=(const char16_t *lhs, const string &rhs) + { + return !(lhs == rhs); + } + +}; + + +template<> +struct string::traits +{ + using string = std::string; + + static void from_str(mysqlx::string &to, const string &from) + { + Impl::from_utf8(to, from); + } + + static string to_str(const mysqlx::string &from) + { + return Impl::to_utf8(from); + } +}; + +template<> +struct string::traits +{ + using string = std::wstring; + + static void from_str(mysqlx::string &to, const string &from) + { + Impl::from_wide(to, from); + } + + static string to_str(const mysqlx::string &from) + { + return Impl::to_wide(from); + } +}; + +template<> +struct string::traits +{ + using string = std::u32string; + + static void from_str(mysqlx::string &to, const string &from) + { + Impl::from_ucs4(to, from); + } + + static string to_str(const mysqlx::string &from) + { + return Impl::to_ucs4(from); + } +}; + + +inline +std::ostream& operator<<(std::ostream &out, const string &str) +{ + const std::string utf8(str); + out << utf8; + return out; +} + + +typedef unsigned long col_count_t; +typedef unsigned long row_count_t; + + +/** + Class representing a region of memory holding raw bytes. + + Method `begin()` returns pointer to the first byte in the + region, `end()` to one past the last byte in the region. + + @note An instance of `bytes` does not store the bytes - + it merely describes a region of memory and is equivalent + to a pair of pointers. It is very cheap to copy `bytes` and + pass them by value. + + @note This class extends std::pair to make + it consistent with how memory regions are described by + std::get_temporary_buffer(). It is also possible to initialize + a `bytes` instance by buffer returned from + std::get_temporary_buffer(), as follows: + + bytes buf = std::get_temporary_buffer(size); + + @ingroup devapi_aux +*/ + +class bytes : public std::pair +{ + +public: + + bytes(const byte *beg_, const byte *end_) + : pair(beg_, end_ - beg_) + {} + + bytes(const byte *beg, size_t len) : pair(beg, len) + {} + + bytes(const char *str) : pair((const byte*)str, 0) + { + if (nullptr != str) + second = strlen(str); + } + + bytes(std::pair buf) : pair(buf) + {} + + bytes() : pair(nullptr, 0) + {} + + bytes(const bytes &) = default; + + virtual const byte* begin() const { return first; } + virtual const byte* end() const { return first + second; } + + size_t length() const { return second; } + size_t size() const { return length(); } + + class Access; + friend Access; +}; + + +/* + Infrastructure for type-agnostic handling of lists + ================================================== + + Template internal::List_initializer<> defined below is used to return lists + of values from public API method so that user can store this list in + a container of his choice. The only requirement is that the container instance + should be constructible from two iterators defining a range of elements + (such constructors exists for standard STL containers, for example). + + Thus, given a public API method foo() which returns a List_initializer<> for + lists of elements of type X, user can do the following: + + My_container cont = foo(); + + The container will be constructed as if this code was executed: + + My_container cont = My_container(begin, end); + + where begin and end are STL iterators defining a range of elements of type X. + This is implemented by defining templated conversion operator. + + Apart from initializing containers, values of List_initializer<> type can + be iterated using a range loop: + + for(X &el : foo()) { ... } + + Otherwise, user should not be able to use List_initializer<> values directly. +*/ + +namespace internal { + +/* + Iterator template. + + It defines an STL input iterator which is implemented using an + implementation object of some type Impl. It is assumed that Impl + has the following methods: + + void iterator_start() - puts iterator in "before begin" position; + bool iterator_next() - moves iterator to next position, returns + false if it was not possible; + Value_type iterator_get() - gets current value. + + An implementation object must be passed to iterator constructor. Iterator + stores only a pointer to this implementation (so it must exist as long as + iterator is used). +*/ + +template< + typename Impl, + typename T = typename std::iterator_traits::value_type, + typename Distance = typename std::iterator_traits::difference_type, + typename Pointer = typename std::iterator_traits::pointer, + typename Reference = typename std::iterator_traits::reference +> +struct Iterator +{ + public: + using iterator_category = std::input_iterator_tag; + using value_type = T; + using difference_type = Distance; + using pointer = Pointer; + using reference = Reference; + + protected: + typename std::remove_reference::type *m_impl = NULL; + bool m_at_end = false; + + public: + Iterator(Impl &impl) : m_impl(&impl) { + m_impl->iterator_start(); + m_at_end = !m_impl->iterator_next(); + } + + Iterator() + : m_at_end(true) + {} + + bool operator==(const Iterator &other) const + { + return (m_at_end && other.m_at_end); + } + + bool operator !=(const Iterator &other) const + { + /* + Compares only if both iterators are at the end + of the sequence. + */ + return !(m_at_end && other.m_at_end); + } + + Iterator& operator++() + { + try { + if (m_impl && !m_at_end) + m_at_end = !m_impl->iterator_next(); + return *this; + } + CATCH_AND_WRAP + } + + T operator*() const + { + if (!m_impl || m_at_end) + THROW("Attempt to dereference null iterator"); + + try { + return m_impl->iterator_get(); + } + CATCH_AND_WRAP + } + + friend Impl; +}; + + +/* + List_initializer object can be used to initialize a container of + arbitrary type U with list of items taken from a source object. + + It is assumed that the source object type Source defines iterator + type and that std::begin/end() return iterators to the beginning + and end of the sequence. The container type U is assumed to have + a constructor from begin/end iterator. + + List_iterator defines begin/end() methods, so it is possible to + iterate over the sequence without storing it in any container. +*/ + +template +class List_initializer +{ +protected: + + Source m_src; + + friend Source; + +public: + + + /* + Arguments given to the constructor are passed to the internal + m_src object. + */ + + template + List_initializer(Ty&&... args) + : m_src(std::forward(args)...) + {} + + /* + Narrow the set of types for which this template is instantiated + to avoid ambiguous conversion errors. It is important to disallow + conversion to std::initializer_list<> because this conversion path + is considered when assigning to STL containers. + */ + + template < + typename U + , typename std::enable_if< + !std::is_same< U, std::initializer_list >::value + >::type* = nullptr + > + operator U() + { + try { + return U(std::begin(m_src), std::end(m_src)); + } + CATCH_AND_WRAP + } + + auto begin() -> decltype(std::begin(m_src)) + { + try { + return std::begin(m_src); + } + CATCH_AND_WRAP + } + + auto end() const -> decltype(std::end(m_src)) + { + try { + return std::end(m_src); + } + CATCH_AND_WRAP + } +}; + + +template +struct iterator_traits +{ + using value_type = typename std::remove_reference::type; + using difference_type + = typename std::iterator_traits::difference_type; + using pointer + = typename std::iterator_traits::pointer; + using reference + = typename std::iterator_traits::reference; +}; + + +/* + This helper template adapts class Impl to be used as a source for + List_initializer<> template. + + Class Impl should be suitable for the Iterator<> template which is used to + build iterators required by List_initializer<>. That is, Impl should + implement iterator_start(), iteratore_next() etc (see Iterator<>). +*/ + +template< + typename Impl, + typename Value_type = typename Impl::Value, + typename Distance = typename iterator_traits::difference_type, + typename Pointer = typename iterator_traits::pointer, + typename Reference = typename iterator_traits::reference +> +class List_source +{ +protected: + + Impl m_impl; + +public: + + template + List_source(Ty&&... args) + : m_impl(std::forward(args)...) + {} + + using iterator = Iterator; + + iterator begin() + { + return iterator(m_impl); + } + + iterator end() const + { + return iterator(); + } +}; + + +/* + A template used to adapt an object of class Impl that represents an array of + values accessed via operator[] to be used as source for List_initializer<> + template. This template uses instance of Impl to implement the iterator + methods iterator_start(), so that it can be used with Iterator<> template. +*/ + +template +class Array_src_impl +{ +protected: + + Impl m_impl; + size_t m_pos = 0; + bool m_at_begin = true; + +public: + + template + Array_src_impl(Ty&&... args) + : m_impl(std::forward(args)...) + {} + + void iterator_start() + { + m_pos = 0; + m_at_begin = true; + } + + bool iterator_next() + { + if (m_at_begin) + m_at_begin = false; + else + m_pos++; + return m_pos < size(); + } + + Value_type iterator_get() + { + return operator[](m_pos); + } + + Value_type operator[](size_t pos) + { + return m_impl[pos]; + } + + size_t size() const + { + return m_impl.size(); + } +}; + + +/* + This template adapts an object of type Impl holding an array of values as + a source for List_initializer<> template. It combines List_source<> and + Array_src_impl<> adapters. +*/ + +template< + typename Impl, + typename Value_type = typename Impl::Value, + typename Distance = typename iterator_traits::difference_type, + typename Pointer = typename iterator_traits::pointer, + typename Reference = typename iterator_traits::reference +> +class Array_source + : public List_source< + Array_src_impl, + Value_type, + Distance, + Pointer, + Reference + > +{ + using Base = List_source< + Array_src_impl, + Value_type, + Distance, + Pointer, + Reference + >; + + using Base::m_impl; + +public: + + using + List_source< + Array_src_impl, + Value_type, + Distance, + Pointer, + Reference + >::List_source; + + Value_type operator[](size_t pos) + { + return m_impl[pos]; + } + + size_t size() const + { + return m_impl.size(); + } +}; + +} // internal + + +/* + Infrastructure for handling variable argument lists + =================================================== + + See documentation of Args_processor<> template. +*/ + +namespace internal { + +/* + Type trait which checks if std::begin()/end() work on objects of given + class C, so that it can be used as a range to iterate over. + + TODO: Make it work also with user-defined begin()/end() functions. + TODO: Make it work with plain C arrays. For example: + + int vals[] = { 1, 2, 3 } + process_args(data, vals) +*/ + +template +class is_range +{ + /* + Note: This overload is taken into account only if std::begin(X) and + std::end(X) expressions are valid. + */ + template + static std::true_type + test( + decltype(std::begin(*((X*)nullptr)))*, + decltype(std::end(*((X*)nullptr)))* + ); + + template + static std::false_type test(...); + +public: + + static const bool value = std::is_same< + std::true_type, + decltype(test(nullptr, nullptr)) + >::value; +}; + + +/* + Class template to be used for uniform processing of variable argument lists + in public API methods. This template handles the cases where arguments + are specified directly as a list: + + method(arg1, arg2, ..., argN) + + or they are taken from a container such as std::list: + + method(container) + + or they are taken from a range of items described by two iterators: + + method(begin, end) + + A class B that is using this template to define a varargs method 'foo' + should define it as follows: + + template + X foo(T... args) + { + Args_processor::process_args(m_impl, args...); + return ...; + } + + Process_args() is a static method of Args_processor<> and therefore + additional context data is passed to it as the first argument. By default + this context is a pointer to internal implementation object, as defined + by the base class B. The process_args() methods does all the necessary + processing of the variable argument list, passing the resulting items + one-by-one to B::process_one() method. Base class B must define this + static method, which takes the context and one data item as arguments. + B::process_one() method can have overloads that handle different types + of data items. + + See devapi/detail/crud.h for usage examples. +*/ + +template +class Args_processor +{ +public: + + /* + Check if item of type T can be passed to Base::process_one() + */ + + template + class can_process + { + template + static std::true_type + test(decltype(Base::process_one(*(D*)nullptr, *(X*)nullptr))*); + + template + static std::false_type test(...); + + public: + + static const bool value + = std::is_same< std::true_type, decltype(test(nullptr)) >::value; + }; + +public: + + /* + Process items from a container. + */ + + template < + typename C, + typename std::enable_if::value>::type* = nullptr, + typename std::enable_if::value>::type* = nullptr + > + static void process_args(D data, C container) + { + // TODO: use (const) reference to avoid copying instances? + for (auto el : container) + { + Base::process_one(data, el); + } + } + + /* + If process_args(data, a, b) is called and a,b are of the same type It + which can not be passed to Base::process_one() then we assume that a and + b are iterators that describe a range of elements to process. + */ + + template < + typename It, + typename std::enable_if::value>::type* = nullptr + > + static void process_args(D data, const It &begin, const It &end) + { + for (It it = begin; it != end; ++it) + { + Base::process_one(data, *it); + } + } + + /* + Process elements given as a varargs list. + */ + + template < + typename T, + typename... R, + typename std::enable_if::value>::type* = nullptr + > + static void process_args(D data, T first, R&&... rest) + { + process_args1(data, first, std::forward(rest)...); + } + +private: + + template < + typename T, + typename... R, + typename std::enable_if::value>::type* = nullptr + > + static void process_args1(D data, T first, R&&... rest) + { + Base::process_one(data, first); + process_args1(data, std::forward(rest)...); + } + + static void process_args1(D) + {} + +}; + +} // internal namespace + +MYSQLX_ABI_END(2,0) +} // mysqlx + + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/crud.h b/Libraries/mysql-connector/include/mysqlx/devapi/crud.h new file mode 100644 index 0000000..c70e6c1 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/crud.h @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_CRUD_H +#define MYSQLX_CRUD_H + +/** + @file + Common templates used to define CRUD operation classes. +*/ + + +#include "common.h" +#include "detail/crud.h" + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +class Session; +class Collection; +class Table; + +namespace internal { + +/* + Factory for constructing concrete implementations of various CRUD + operations. All these implementations implement the base Executable_if + interface. + + Note: The caller of mk_xxx() method takes ownership of the returned + implementation object. +*/ + +struct PUBLIC_API Crud_factory +{ + using Impl = common::Executable_if; + + static Impl* mk_add(Collection &coll); + static Impl* mk_remove(Collection &coll, const string &expr); + static Impl* mk_find(Collection &coll); + static Impl* mk_find(Collection &coll, const string &expr); + static Impl* mk_modify(Collection &coll, const string &expr); + + static Impl* mk_insert(Table &tbl); + static Impl* mk_select(Table &tbl); + static Impl* mk_update(Table &tbl); + static Impl* mk_remove(Table &tbl); + + static Impl* mk_sql(Session &sess, const string &sql); +}; + + +} // internal + + +/* + Different CRUD operation classes derive from `Executable` which defines + the `execute()` method that executes given operation. Derived classes + define additional methods that can modify the operation before it gets + executed. + + The hierarchy of classes reflects the grammar that defines the order in which + fluent API calls can be done. It is built using templates, such as Offset<> + below, which add one API call on top of base class which defines remaining + API calls that can be called later. For example, type + + Limit< Offset< Executable<...> > > + + represents an operation for which first .limit() can be called, followed by + .offset() and then finally .execute(). See classes like + Collection_find_base in collection_crud.h for more examples. + + Each template assumes that its base class defines method 'get_impl()' which + returns a pointer to the internal implementation object. It also assumes that + this implementation is of appropriate type and can be casted to + the appropriate interface type. For example Limit<> template assumes + that the implementation type can be casted to Limit_if type. +*/ + + +/** + @brief The LockContention enum defines constants for defining + the row locking contention for `Set_lock::lockExclusive()` + and `Set_lock::lockShared()` methods. + @see https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html#innodb-locking-reads-nowait-skip-locked +*/ + +enum_class LockContention +{ +#define DEVAPI_LOCK_CONTENTION_ENUM(X,N) X = N, + + LOCK_CONTENTION_LIST(DEVAPI_LOCK_CONTENTION_ENUM) +}; + +namespace internal { + +/** + Template for defining fluent api for CRUD operations. +*/ + +template +class Offset + : public Base +{ + using Operation = Base; + +public: + + /** + Skip the given number of items (rows or documents) before starting + to perform the operation. + */ + + Operation& offset(unsigned rows) + { + try { + get_impl()->set_offset(rows); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Limit_if; + + Impl* get_impl() + { + return static_cast(Base::get_impl()); + } +}; + + +/// @copydoc Offset + +template +class Limit + : public Base +{ + using Operation = Base; + +public: + + /** + %Limit the operation to the given number of items (rows or documents). + */ + + Operation& limit(unsigned items) + { + try { + get_impl()->set_limit(items); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Limit_if; + + Impl* get_impl() + { + return static_cast(Base::get_impl()); + } +}; + + +/// @copydoc Offset + +template +class Sort + : public Base + , Sort_detail +{ + using Operation = Base; + +public: + + /** + Specify ordering of documents in a query results. + + Arguments are one or more strings of the form `" "` where + `` gives the value to sort on and `` is a sorting direction + `ASC` or `DESC`. + */ + + template + Operation& sort(Type... spec) + { + try { + get_impl()->clear_sort(); + add_sort(get_impl(), spec...); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Sort_if; + + Impl* get_impl() + { + return static_cast(Base::get_impl()); + } +}; + + +/// @copydoc Offset + +template +class Order_by + : public Base + , Sort_detail +{ + using Operation = Base; + +public: + + /** + Specify ordering of rows in a query results. + + Arguments are one or more strings of the form `" "` where + `` gives the value to sort on and `` is a sorting direction + `ASC` or `DESC`. + */ + + template + Operation& orderBy(Type... spec) + { + try { + get_impl()->clear_sort(); + add_sort(get_impl(), spec...); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Sort_if; + + Impl* get_impl() + { + return static_cast(Base::get_impl()); + } +}; + + +/// @copydoc Offset + +template +class Having + : public Base +{ + using Operation = Base; + +public: + + /** + Specify filter over grouped results of a query. + + The argument is a Boolean expression which can use aggregation functions. + */ + + Operation& having(const string& having_spec) + { + try { + get_impl()->set_having(having_spec); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Having_if; + + Impl* get_impl() + { + return static_cast(Base::get_impl()); + } +}; + + +/// @copydoc Offset + +template +class Group_by + : public Base + , Group_by_detail +{ + using Operation = Base; + +public: + + /** + Specify grouping of items in a query result. + + Arguments are a one or more expressions. Documents/rows for which + expressions evaluate to the same value are grouped together. + */ + + template + Operation& groupBy(Expr... group_by_spec) + { + try { + get_impl()->clear_group_by(); + do_group_by(get_impl(), group_by_spec...); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Group_by_if; + + Impl* get_impl() + { + return static_cast(Base::get_impl()); + } +}; + + +/// @copydoc Offset + +template +class Bind_placeholders + : public Base + , Bind_detail +{ + using BindOperation = Bind_placeholders; + +public: + + /** + Specify values for '?' placeholders in a query. + + One or more values can be specified in a single call to bind(). A query + can be executed only if values for all placeholders have been specified. + */ + + template + BindOperation& bind(Types&&... vals) + { + try { + add_params(get_impl(), std::forward(vals)...); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Bind_if; + + Impl* get_impl() + { + return static_cast(Base::get_impl()); + } +}; + + +/// @copydoc Offset + +template +class Bind_parameters + : public Base +{ + using BindOperation = Bind_parameters; + using Operation = Base; + +public: + + /** + Bind parameter with given name to the given value. + + A statement or query can be executed only if all named parameters used by + it are bound to values. + */ + + BindOperation& bind(const string ¶meter, const Value &val) + { + //TODO: Protocol supports Document and Array... but common::Values doesn't! + if (Value::DOCUMENT == val.getType()) + throw_error("Can not bind a parameter to a document"); + + if (Value::ARRAY == val.getType()) + throw_error("Can not bind a parameter to an array"); + + try { + get_impl()->add_param(parameter, (const common::Value&)val); + return *this; + } + CATCH_AND_WRAP + } + + /** + Bind parameters to values given by a map from parameter + names to their values. + */ + + template + Operation& bind(const Map &args) + { + for (const auto &keyval : args) + { + bind(keyval.first, keyval.second); + } + return *this; + } + +protected: + + using Impl = common::Bind_if; + + Impl* get_impl() + { + return static_cast(Base::get_impl()); + } +}; + + +/// @copydoc Offset + +template +class Set_lock + : public Base +{ + using Operation = Base; + +public: + + /** + Set a shared mode lock on any rows/documents that are read. + + Other sessions can read, but not modify locked rows/documents. + */ + + Operation& + lockShared(LockContention contention= LockContention::DEFAULT) + { + get_impl()->set_lock_mode(common::Lock_mode::SHARED, + common::Lock_contention((unsigned)contention)); + return *this; + } + + /** + Set an exclusive mode lock on any rows/documents that are read. + + Other sessions are blocked from modifying, locking, or reading the data + in certain transaction isolation levels. The lock is released + when the transaction is committed or rolled back. + */ + + Operation& + lockExclusive(LockContention contention = LockContention::DEFAULT) + { + get_impl()->set_lock_mode(common::Lock_mode::EXCLUSIVE, + common::Lock_contention((unsigned)contention)); + return *this; + } + +protected: + + using Impl = IMPL; + + Impl* get_impl() + { + return static_cast(Base::get_impl()); + } +}; + + +} // internal +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/detail/crud.h b/Libraries/mysql-connector/include/mysqlx/devapi/detail/crud.h new file mode 100644 index 0000000..f9ea4f0 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/detail/crud.h @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_DETAIL_CRUD_H +#define MYSQLX_DETAIL_CRUD_H + +/** + @file + Details for public API classes representing CRUD operations. +*/ + + +#include "../common.h" +#include "../executable.h" + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +namespace internal { + + +struct PUBLIC_API Bind_detail +{ +protected: + + using Impl = common::Bind_if; + using Args_prc = Args_processor; + + static void process_one(Impl *impl, const Value &val) + { + impl->add_param((const common::Value&)val); + } + + template + static void add_params(Impl *impl, T&&... vals) + { + Args_prc::process_args(impl, std::forward(vals)...); + } + + friend Args_prc; +}; + + +struct PUBLIC_API Sort_detail +{ +protected: + + using Impl = common::Sort_if; + using Args_prc = Args_processor; + + static void process_one(Impl *impl, const string &ord_spec) + { + impl->add_sort(ord_spec); + } + + template + static void add_sort(Impl *impl, T... args) + { + Args_prc::process_args(impl, args...); + } + + friend Args_prc; +}; + + +struct PUBLIC_API Group_by_detail +{ +protected: + + using Impl = common::Group_by_if; + using Args_prc = Args_processor; + + static void process_one(Impl *impl, const string &spec) + { + impl->add_group_by(spec); + } + + template + static void do_group_by(Impl *impl, T... args) + { + Args_prc::process_args(impl, args...); + } + + friend Args_prc; +}; + + +struct PUBLIC_API Proj_detail +{ +protected: + + using Impl = common::Proj_if; + using Args_prc = Args_processor; + + static void process_one(Impl *impl, const string &spec) + { + impl->add_proj(spec); + } + + template + static void add_proj(Impl *impl, T... proj_spec) + { + Args_prc::process_args(impl, proj_spec...); + } + + friend Args_prc; +}; + + +struct PUBLIC_API Collection_add_detail +{ +protected: + + using Impl = common::Collection_add_if; + using Args_prc = Args_processor; + + static void process_one(Impl *impl, const string &json) + { + impl->add_json(json); + } + + static void process_one(Impl *impl, const DbDoc &doc) + { + // TODO: Do it better when we support sending structured + // document descriptions to the server. + + std::ostringstream buf; + buf << doc; + // Note: utf8 conversion using mysqlx::string. + impl->add_json(mysqlx::string(buf.str())); + } + + template + static void do_add(Impl *impl, T... args) + { + Args_prc::process_args(impl, args...); + } + + friend Args_prc; +}; + + +struct PUBLIC_API Collection_find_detail +{ +protected: + + using Impl = common::Proj_if; + using Args_prc = Args_processor; + + static void process_one(Impl *impl, const string &proj) + { + impl->add_proj(proj); + } + + + static void do_fields(Impl *impl, const Expression &proj) + { + impl->set_proj(proj.get()); + } + + /* + Note: If e is an expression (of type Expression) then only + .fields(e) is valid - the multi-argument variant .fields(e,...) + should be disabled. + */ + + template < + typename T, typename... R, + typename std::enable_if::value>::type* = nullptr + > + static void do_fields(Impl *impl, T first, R... rest) + { + Args_prc::process_args(impl, first, rest...); + } + + friend Args_prc; +}; + + +struct PUBLIC_API Table_insert_detail +{ +protected: + + using Row_impl = internal::Row_detail::Impl; + using Impl = common::Table_insert_if; + + /* + Helper methods which pass column/row information to the + internal implementation object. + */ + + struct Add_column + { + static void process_one(Impl *impl, const string &col) + { + impl->add_column(col); + } + }; + + struct Add_value + { + using Impl = std::pair; + + static void process_one(Impl *impl, const mysqlx::Value &val) + { + impl->first.set((impl->second)++, val); + } + }; + + struct Add_row + { + static void process_one(Impl *impl, const Row &row) + { + impl->add_row(*row.m_impl); + } + }; + + template + static void add_columns(Impl *impl, T... args) + { + Args_processor::process_args(impl, args...); + } + + template + static void add_rows(Impl *impl, T... args) + { + Args_processor::process_args(impl, args...); + } + + template + static void add_values(Impl *impl, T... args) + { + Add_value::Impl row{ {}, 0 }; + Args_processor::process_args(&row, args...); + Add_row::process_one(impl, row.first); + } + + friend Args_processor; + friend Args_processor; + friend Args_processor; + +}; + + +using Table_select_detail = Proj_detail; + +} // internal + +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/detail/error.h b/Libraries/mysql-connector/include/mysqlx/devapi/detail/error.h new file mode 100644 index 0000000..0406b97 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/detail/error.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_DETAIL_ERROR_H +#define MYSQLX_DETAIL_ERROR_H + +/** + @file + Classes used to access query and command execution results. +*/ + +#include "../common.h" + +//#include + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +namespace internal { + +class Result_detail; + +class Warning_detail + : public virtual common::Printable +{ +protected: + + byte m_level; + uint16_t m_code; + string m_msg; + + Warning_detail(Warning_detail&&) = default; + Warning_detail(const Warning_detail&) = default; + + Warning_detail(byte level, uint16_t code, const std::string &msg) + : m_level(level), m_code(code), m_msg(msg) + {} + + void print(std::ostream &) const override; + + friend Result_detail; +}; + + +} // internal namespace +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/detail/result.h b/Libraries/mysql-connector/include/mysqlx/devapi/detail/result.h new file mode 100644 index 0000000..ad64dc7 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/detail/result.h @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_DETAIL_RESULT_H +#define MYSQLX_DETAIL_RESULT_H + +/** + @file + Details for public API result classes. +*/ + + +#include "../common.h" +#include "../error.h" +#include "../document.h" +#include "../row.h" +#include "../collations.h" + +#include + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +class RowResult; +class Column; +class Columns; +class Session; + +namespace common { + +class Result_init; +class Column_info; +class Result_impl; + +} // common + + +namespace internal { + + +struct Session_detail; + + +class PUBLIC_API Result_detail +{ + // Disable copy semantics for result classes. + + Result_detail(const Result_detail&) = delete; + Result_detail& operator=(const Result_detail&) = delete; + +public: + + using Impl = common::Result_impl; + +protected: + + Result_detail(common::Result_init&); + + // Note: move semantics is implemented by move assignment operator. + + Result_detail(Result_detail &&other) + { + operator=(std::move(other)); + } + + Result_detail& operator=(Result_detail&&); + + Result_detail() = default; + virtual ~Result_detail(); + + Impl& get_impl(); + + const Impl& get_impl() const + { + return const_cast(this)->get_impl(); + } + + void check_result() const; + + uint64_t get_affected_rows() const; + uint64_t get_auto_increment() const; + + using DocIdList = internal::List_initializer&>; + + DocIdList get_generated_ids() const; + + // Handling multi-results + + bool has_data() const; + + // Note: needs to be called before accessing the first result set. + bool next_result(); + +protected: + + Impl *m_impl = nullptr; + bool m_owns_impl = false; + + /* + Source for WarningList initializer. + */ + + struct Warning_src + { + using Value = Warning; + + Result_detail &m_res; + + Warning_src(Result_detail &res) + : m_res(res) + {} + + size_t size() const + { + return m_res.get_warning_count(); + } + + Warning operator[](size_t pos) + { + return m_res.get_warning(pos); + } + }; + +public: + + using WarningList = internal::List_initializer>; + +protected: + + unsigned get_warning_count() const; + Warning get_warning(size_t pos); + + WarningList get_warnings() + { + get_warning_count(); + return { *this }; + } + +public: + + friend Session_detail; + friend List_initializer; +}; + + +/* + This class keeps a reference to column information stored in a + common::Column_info<> instance. The meta-data is exposed in format expected + by X DevAPI meta-data access methods. In particualr the CDK type and encoding + format information is translated to X DevAPI type information. For example, + a CDK column of type FLOAT can be reported as DevAPI type FLOAT, DOUBLE + or DECIMAL, depending on the encoding format that was reported by CDK. This + translation happens in Column::getType() method. + + Additional encoding information is exposed via other methods such as + is_signed(). +*/ + +class PUBLIC_API Column_detail + : virtual common::Printable +{ +protected: + + using Impl = common::Column_info; + + const Impl *m_impl = nullptr; + + Column_detail(const Impl *impl) + : m_impl(impl) + {} + + const Impl& get_impl() const + { + assert(m_impl); + return *m_impl; + } + + string get_name() const; + string get_label() const; + string get_schema_name() const; + string get_table_name() const; + string get_table_label() const; + + // Note: should return values of mysqlx::Type enum constants + + unsigned get_type() const; + + CharacterSet get_charset() const; + const CollationInfo& get_collation() const; + + unsigned long get_length() const; + unsigned short get_decimals() const; + + bool is_signed() const; + bool is_padded() const; + + void print(std::ostream&) const override; + +protected: + + Column_detail() = default; + Column_detail(const Column_detail&) = default; + Column_detail(Column_detail&&) = default; + + Column_detail& operator=(const Column_detail&) = default; + +public: + + friend Impl; + friend Result_detail; + friend RowResult; + + struct INTERNAL Access; + friend Access; +}; + + +/* + A wrapper around column meta-data class COL that adds copy semantics + and default ctor. This is required by Columns_detail class which uses + an STL container to store data for several columns. +*/ + +template +struct Column_storage + : public COL +{ + Column_storage(const typename COL::Impl *impl) + : COL(impl) + {} + + // Note: these members are needed to use it with std::deque<> + + Column_storage() = default; + Column_storage(const Column_storage&) = default; + Column_storage& operator=(const Column_storage&) = default; +}; + + +template class Row_result_detail; + + +/* + Class holding meta-data information for all columns in a result. + + Template parameter COL is a class used to store information about a single + column. It is made into template parameter because full definition of + the actuall mysqlx::Column class is not available in this header. + + Note: Because this class is implemented using std::deque<>, we wrap COL + class with the Column_storage<> wrapper to provide copy semantics and default + ctor required by this STL container. +*/ + +template +class Columns_detail + : public std::deque> +{ + Columns_detail(const Columns_detail&) = delete; + +protected: + + Columns_detail() = default; + Columns_detail(Columns_detail&&) = default; + Columns_detail& operator=(Columns_detail&&) = default; + + void init(const internal::Result_detail::Impl&); + + ///@cond IGNORE + friend internal::Row_result_detail; + ///@endcond +}; + + +/* + COLS is a class used to store information about result columns. It is made + into template parameter because the actual mysqlx::Columns class, with + the public API for accessing column information, is defined in the top-level + header devapi/result.h. + + The COLS class should have move semantics to enable move-semantics for result + objects. +*/ + +template +class Row_result_detail + : public Result_detail +{ +public: + + using iterator = Iterator; + using RowList = List_initializer; + using Columns = COLS; + + iterator begin() + { + return iterator(*this); + } + + iterator end() const + { + return iterator(); + } + +private: + + // Row iterator implementation + + Row m_row; + + using Value = Row; + + void iterator_start() {} + + bool iterator_next(); + + Value iterator_get() + { + return m_row; + } + + +protected: + + Row_result_detail() = default; + Row_result_detail(common::Result_init&); + + Row_result_detail(Row_result_detail&&) = default; + Row_result_detail& operator=(Row_result_detail&&) = default; + + RowList get_rows() + { + /* + Construct RowList instance passing reference to this Row_result_detail + object which acts as a source for the list initializer. + */ + return *this; + } + + row_count_t row_count(); + + Row get_row() + { + if (!iterator_next()) + return Row(); + return iterator_get(); + } + +private: + + // Storage for result column information. + + Columns m_cols; + +protected: + + col_count_t col_count() const; + const Column& get_column(col_count_t) const; + const Columns& get_columns() const; + + bool next_result() + { + bool rc = Result_detail::next_result(); + if (rc) + m_cols.init(get_impl()); + return rc; + } + + friend iterator; + friend RowResult; + friend Columns; +}; + + +// Document based results +// ---------------------- + +class PUBLIC_API Doc_result_detail + : public Result_detail +{ +public: + + using iterator = Iterator; + using DocList = List_initializer; + + iterator begin() + { + return iterator(*this); + } + + iterator end() const + { + return iterator(); + } + +private: + + // iterator implementation + + DbDoc m_cur_doc; + + void iterator_start() {} + + bool iterator_next(); + + DbDoc iterator_get() + { + return m_cur_doc; + } + +protected: + + Doc_result_detail() = default; + + Doc_result_detail(common::Result_init &init) + : Result_detail(init) + {} + + DbDoc get_doc() + { + if (!iterator_next()) + return DbDoc(); + return iterator_get(); + } + + uint64_t count(); + + DocList get_docs() + { + return *this; + } + + friend Impl; + friend iterator; +}; + + +} // internal namespace +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/detail/row.h b/Libraries/mysql-connector/include/mysqlx/devapi/detail/row.h new file mode 100644 index 0000000..c413e53 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/detail/row.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_DETAIL_ROW_H +#define MYSQLX_DETAIL_ROW_H + +/** + @file + Details for Row class. +*/ + + +#include "../common.h" +#include "../document.h" + +#include + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +class Columns; + +namespace internal { + +template class Row_result_detail; +struct Table_insert_detail; + + +class PUBLIC_API Row_detail +{ +protected: + + class INTERNAL Impl; + DLL_WARNINGS_PUSH + std::shared_ptr m_impl; + DLL_WARNINGS_POP + + Row_detail() = default; + + Row_detail(std::shared_ptr &&impl) + { + m_impl = std::move(impl); + } + + col_count_t col_count() const; + bytes get_bytes(col_count_t) const; + Value& get_val(col_count_t); + + void clear() + { + m_impl.reset(); + } + + Impl& get_impl(); + + const Impl& get_impl() const + { + return const_cast(this)->get_impl(); + } + + void ensure_impl(); + + using Args_prc = Args_processor*>; + + template + void set_values(col_count_t pos, Types... args) + { + ensure_impl(); + assert(m_impl); + std::pair data{ m_impl.get(), pos }; + Args_prc::process_args(&data, args...); + } + + static void process_one(std::pair*, const Value &val); + + friend Table_insert_detail; + friend Row_result_detail; + friend Args_prc; +}; + + +} // internal namespace +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/detail/session.h b/Libraries/mysql-connector/include/mysqlx/devapi/detail/session.h new file mode 100644 index 0000000..cf4f6d4 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/detail/session.h @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_DETAIL_SESSION_H +#define MYSQLX_DETAIL_SESSION_H + +#include "../common.h" +#include "../crud.h" + +#include + +namespace cdk { + class Session; +} + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +class Value; +class Session; +class Schema; +class Table; +class Collection; +class CollectionOptions; + +namespace common { + class Session_impl; + class Session_pool; + using Shared_session_pool = std::shared_ptr; + class Result_init; + class Result_impl; +} + +namespace internal { + +class Schema_detail; +using Client_impl = common::Session_pool; +using Shared_client_impl = std::shared_ptr; +using Session_impl = common::Session_impl; +using Shared_session_impl = std::shared_ptr; + + +/* + Base class for database objects. Can't be used alone. +*/ + +class PUBLIC_API Db_obj_base +{ +protected: + + DLL_WARNINGS_PUSH + Shared_session_impl m_sess; + string m_name; + DLL_WARNINGS_POP + + Db_obj_base(const Shared_session_impl& sess, const string& name) + : m_sess(sess), m_name(name) + {} + + virtual ~Db_obj_base() + {} +}; + + +class PUBLIC_API Collection_detail + : public Db_obj_base +{ +protected: + + Collection_detail(const Shared_session_impl &sess, const string &name) + : Db_obj_base(sess, name) + {} + + virtual Schema_detail& get_schema() = 0; + + Result add_or_replace_one(const string &id, Value&&, bool); + + void index_drop(const string &name); + void index_create(const string &name, Value &&spec); +}; + + +// --------------------------------------------------------------------------- + +/* + Base class for classes to be used by common::List_source<> which get item + from query results. + + It assumes that the first column in the results contains string + data. An instance of this class iterates over the string data in the + result until all rows are consumed. + + Derived class must send the query to the server and set m_res member to point + at the result of this query. +*/ + +struct PUBLIC_API Query_src +{ + using Value = string; + using Res_impl = common::Result_impl; + + Res_impl *m_res = nullptr; + const void *m_row = nullptr; + +public: + + Query_src() + {} + + Query_src(Query_src &&other) + : m_res(other.m_res) + { + // Note: only one instance of Query_src owns m_res. + other.m_res = nullptr; + } + + Query_src(const Query_src&) = delete; + + virtual ~Query_src(); + + virtual void iterator_start() + { + assert(m_res); + } + + bool iterator_next(); + string iterator_get(); +}; + + +// --------------------------------------------------------------------------- + + +class PUBLIC_API Schema_detail + : public Db_obj_base +{ +protected: + + enum Obj_type { COLLECTION, TABLE }; + + /* + Sources for lists of schema objects and their names. + + When constructing a source, a SQL style patter on object names is + given as ctor parameter -- only object matching the pattern are listed. + Name_src accepts a parameter which tells whether names of tables or + collections should be listed. + */ + + struct PUBLIC_API Name_src + : public Query_src + { + const Schema &m_schema; + Name_src(const Schema&, Obj_type, const string &pattern); + }; + + struct PUBLIC_API Collection_src + : Name_src + { + using Value = Collection; + + Collection_src(const Schema &sch, const string &pattern) + : Name_src(sch, COLLECTION, pattern) + {} + + using Name_src::iterator_start; + using Name_src::iterator_next; + Collection iterator_get(); + }; + + struct PUBLIC_API Table_src + : Name_src + { + using Value = Table; + + Table_src(const Schema &sch, const string &pattern) + : Name_src(sch, TABLE, pattern) + {} + + using Name_src::iterator_start; + using Name_src::iterator_next; + Table iterator_get(); + }; + + Schema_detail(const Shared_session_impl &sess, const string &name) + : Db_obj_base(sess, name) + {} + +public: + + using CollectionList = List_initializer>; + using TableList = List_initializer>; + using StringList = List_initializer>; + +protected: + + + void create_collection(const mysqlx::string &name, + CollectionOptions options); + void modify_collection(const mysqlx::string &name, + CollectionOptions options); + void drop_collection(const string &name); + + friend Collection_detail; + + struct Access; + friend Access; +}; + + +/* + Class representing an SQL statement that can be executed on the server. +*/ + +struct SQL_statement; + +using SQL_statement_cmd = Executable; + +struct SQL_statement + : public Bind_placeholders< SQL_statement_cmd > +{ + SQL_statement(Session *sess, const string &query) + { + assert(sess); + try { + reset(internal::Crud_factory::mk_sql(*sess, query)); + } + CATCH_AND_WRAP + } + + SQL_statement(SQL_statement_cmd &other) + { + SQL_statement_cmd::operator=(other); + } + + SQL_statement(SQL_statement_cmd &&other) + { + SQL_statement_cmd::operator=(std::move(other)); + } +}; + + +struct Session_detail; + +struct PUBLIC_API Client_detail +{ + + // Disable copy semantics for client class. + + Client_detail(const Client_detail&) = delete; + Client_detail& operator=(const Client_detail&) = delete; + + + + Client_detail(common::Settings_impl &settings); + //Client_detail(common::Settings_impl &&settings); + + void close(); + +protected: + + Client_detail(Client_detail && other) + { + m_impl = other.m_impl; + other.m_impl.reset(); + } + + common::Shared_session_pool& get_session_pool(); + + + struct INTERNAL Impl; + + DLL_WARNINGS_PUSH + Shared_client_impl m_impl = NULL; + DLL_WARNINGS_POP + + friend Session; +}; + + +struct PUBLIC_API Session_detail +{ + // Disable copy semantics for session class. + + Session_detail(const Session_detail&) = delete; + Session_detail& operator=(const Session_detail&) = delete; + + /* + Sources for lists of schemata and schema names. Only schemata matching + the given SQL-style pattern are listed. + */ + + struct PUBLIC_API Name_src + : public Query_src + { + const Session &m_sess; + Name_src(const Session&, const string &pattern); + }; + + struct PUBLIC_API Schema_src + : Name_src + { + using Value = Schema; + + Schema_src(Session &sess, const string &pattern) + : Name_src(sess, pattern) + {} + + Schema_src(Session &sess) + : Schema_src(sess, "%") + {} + + using Name_src::iterator_start; + using Name_src::iterator_next; + Schema iterator_get(); + }; + +public: + + using SchemaList = List_initializer>; + +protected: + + Session_detail(Session_detail && other) + { + m_impl = other.m_impl; + other.m_impl.reset(); + } + + + struct INTERNAL Impl; + + /* + Note: Session implementation is shared with result objects because it + must exists as long as result implementation exists. This means that + even when session object is deleted, its implementation can still hang + around. + */ + + DLL_WARNINGS_PUSH + Shared_session_impl m_impl = NULL; + DLL_WARNINGS_POP + + Session_detail(common::Settings_impl&); + Session_detail(common::Shared_session_pool&); + + virtual ~Session_detail() + { + try { + if (m_impl) + close(); + } + catch (...) {} + } + + void create_schema(const string &name, bool reuse); + void drop_schema(const string &name); + string get_default_schema_name(); + + void start_transaction(); + void commit(); + void rollback(const string &sp = string()); + string savepoint_set(const string &sp = string()); + void savepoint_remove(const string&); + + + common::Session_impl& get_impl() + { + if (!m_impl) + THROW("Invalid session"); + return *m_impl; + } + + INTERNAL cdk::Session& get_cdk_session(); + + void close(); + + /* + Do necessary cleanups before sending new command to the server. + */ + void prepare_for_cmd(); + +public: + + /// @cond IGNORED + friend Result_detail::Impl; + friend internal::Crud_factory; + /// @endcond +}; + + +} // internal namespace + +MYSQLX_ABI_END(2,0) +} // mysqlx namespace + + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/detail/settings.h b/Libraries/mysql-connector/include/mysqlx/devapi/detail/settings.h new file mode 100644 index 0000000..87d68fa --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/detail/settings.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_DETAIL_SETTINGS_H +#define MYSQLX_DETAIL_SETTINGS_H + +#include "../common.h" +#include "../document.h" +#include + +#include +#include + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +namespace internal { + +/* + Note: Options and SSLMode enumerations are given by Traits template parameter + to allow defining (and documenting) them in the main settings.h header. +*/ + + +template +class Settings_detail + : public common::Settings_impl +{ + using Value = mysqlx::Value; + using Option = typename Traits::Options; + using COption = typename Traits::COptions; + using SSLMode = typename Traits::SSLMode; + using AuthMethod = typename Traits::AuthMethod; + using CompressionMode = typename Traits::CompressionMode; + +public: + + template + void set(OPT opt, Ty&&... rest) + { + do_set(get_options(opt, std::forward(rest)...)); + } + +protected: + + /* + Declare options that require specific type of value (mostly enumerations). + For such options we do not accept setting them to arbitrary values. Instead + an overload of opt_val() with appropriate type will be used to set value + of the option. + */ + +#define OPT_VAL_TYPE(X) \ + X(SSL_MODE,SSLMode) \ + X(AUTH,AuthMethod) + +#define CHECK_OPT(Opt,Type) \ + if (opt == Session_option_impl::Opt) \ + throw Error(#Opt "setting requires value of type " #Type); + + /* + Store option value in Value object (with basic run-time type checks) + TODO: More precise type checking using per-option types. + */ + + static Value opt_val(int opt, Value &&val) + { + OPT_VAL_TYPE(CHECK_OPT) + return std::move(val); + } + + /* + For types which are not convertible to Value, but can be converted to string + go through string conversion. + */ + + static Value opt_val(int opt, std::nullptr_t) + { + return opt_val(opt, Value()); + } + + template < + typename V, + typename std::enable_if::value>::type* + = nullptr + > + static Value opt_val(int opt, V &&val) + { + return opt_val(opt, Value(string(val))); + } + + static Value opt_val(int opt, SSLMode m) + { + if (opt != Session_option_impl::SSL_MODE) + throw Error( + "SessionSettings::SSLMode value can only be used on SSL_MODE setting." + ); + return unsigned(m); + } + + static Value opt_val(int opt, AuthMethod m) + { + if (opt != Session_option_impl::AUTH) + throw Error( + "SessionSettings::AuthMethod value can only be used on AUTH setting." + ); + return unsigned(m); + } + + static Value opt_val(int opt, CompressionMode m) + { + if (opt != Session_option_impl::COMPRESSION) + throw Error( + "SessionSettings::CompressionMode value can only be used on COMPRESSION setting." + ); + return unsigned(m); + } + + // Note: is_range is true for string types, which should not be treated + // as arrays of characters, but as single Values. + + template < + typename C, + typename std::enable_if::value>::type* = nullptr, + typename std::enable_if::value>::type* + = nullptr + > + static Value opt_val(int , const C &container) + { + return Value(std::begin(container), std::end(container)); + } + + template + static Value opt_val( + int opt, const std::chrono::duration<_Rep, _Period> &duration + ) + { + if (opt != Session_option_impl::CONNECT_TIMEOUT && + opt != Client_option_impl::POOL_QUEUE_TIMEOUT && + opt != Client_option_impl::POOL_MAX_IDLE_TIME) + { + std::stringstream err_msg; + err_msg << "Option " << option_name(opt) << " does not accept time value"; + throw_error(err_msg.str().c_str()); + } + + return Value(std::chrono::duration_cast(duration) + .count()); + } + + // Handle values that are directly convertible to Value. + + template < + typename V, + typename std::enable_if::value>::type* + = nullptr, + typename std::enable_if::value>::type* + = nullptr + > + static Value opt_val(int opt, V &&val) + { + return opt_val(opt, Value(val)); + } + + using session_opt_val_t = std::pair; + using session_opt_list_t = std::list; + + /* + Set list of options with consistency checks. + + This operation is atomic - settings are changed only if all options could + be set without error, otherwise settings remain unchanged. + */ + + void do_set(session_opt_list_t&&); + + // Note: for ABI compatibility + void PUBLIC_API do_set(std::list>&&); + + /* + Templates that collect varargs list of options into opt_list_t list + that can be passed to do_set(). + */ + + template + static session_opt_list_t get_options() + { + return {}; + } + + /* + Note: if we ever support options without values, another overload is + needed: get_options(Option opt, Option opt1, R&... rest). + */ + + template < + bool session_only, typename V, typename... Ty, + typename std::enable_if::type* = nullptr + > + static session_opt_list_t get_options(Option opt, V&& val, Ty&&... rest) + { + int oo(static_cast(opt)); + session_opt_list_t opts = get_options(std::forward(rest)...); + opts.emplace_front(oo, + Settings_detail::opt_val(oo, std::forward(val)) + ); + return opts; + } + + template < + bool session_only, typename V, typename... Ty, + typename std::enable_if::type* = nullptr + > + static session_opt_list_t get_options(COption opt, V&& val, Ty&&... rest) + { + int oo(static_cast(opt)); + session_opt_list_t opts = get_options(std::forward(rest)...); + opts.emplace_front( + oo, + Settings_detail::opt_val(oo, std::forward(val)) + ); + return opts; + } + + /* + Note: Methods below rely on the fact that DevAPI SessionOption constants + have the same numeric values as common::Settings_impl::Option ones. + */ + + bool has_option(COption opt) const + { + return Settings_impl::has_option(opt); + } + + Value get(COption opt) + { + return Settings_impl::get(opt); + } + +}; + + +} // internal namespace + +MYSQLX_ABI_END(2,0) +} // mysqlx namespace + +#endif + diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/document.h b/Libraries/mysql-connector/include/mysqlx/devapi/document.h new file mode 100644 index 0000000..442dab7 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/document.h @@ -0,0 +1,1081 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_DOCUMENT_H +#define MYSQLX_DOCUMENT_H + +/** + @file + Declaration of DbDoc and related classes. +*/ + +#include "common.h" + +#include +#include +#include +#include +#include + +#undef min +#undef max + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +class Value; +class DbDoc; +class DocResult; +class SessionSettings; + +namespace internal{ +class Schema_detail; + +} //internal + +using Field = std::string; + + +// Document class +// ============== + + +/** + Represents a collection of key-value pairs where value can be a scalar + or another document. + + @note Internal document implementation is shared among DbDoc instances + and thus using DbDoc objects should be cheap. + + @ingroup devapi_res +*/ + +class PUBLIC_API DbDoc + : public common::Printable +{ + // TODO: move PUBLIC_API stuff to a detail class + + class INTERNAL Impl; + +DLL_WARNINGS_PUSH + + std::shared_ptr m_impl; + +DLL_WARNINGS_POP + + INTERNAL DbDoc(const std::shared_ptr&); + + const char* get_json() const; + +public: + + /** + Create null document instance. + + @note Null document is different from empty document that has + no fields. + */ + + DbDoc() {} + + /** + Creates DbDoc instance out of given JSON string description. + */ + + explicit DbDoc(const std::string&); + explicit DbDoc(std::string&&); + + + /** + Check if document is null + */ + + bool isNull() const { return NULL == m_impl.get(); } + operator bool() const { return !isNull(); } + + + /** + Check if named field is a top-level field in the document. + */ + + virtual bool hasField(const Field&) const; + + + /** + Return Value::XXX constant that identifies type of value + stored at given field. + */ + + virtual int fieldType(const Field&) const; + + /** + Return value of given field. + */ + + virtual const Value& operator[](const Field&) const; + + const Value& operator[](const char *name) const + { + return this->operator[](Field(name)); + } + + const Value& operator[](const mysqlx::string &name) const + { + return this->operator[](Field(name)); + } + + + /** + Print JSON description of the document. + */ + + virtual void print(std::ostream&) const; + + /** + Iterator instance can iterate over (top-level) fields of a document. + A new iterator is obtained from begin() method. + + @note Only one instance of an iterator can be used at a time (not + thread safe!). + */ + + class Iterator; + + virtual Iterator begin(); + virtual Iterator end(); + + friend Impl; + friend DocResult; + friend Value; + /// \cond Note: Ignore by doxygen + friend internal::Schema_detail; + /// \endcond +}; + + +class PUBLIC_API DbDoc::Iterator +{ + DLL_WARNINGS_PUSH + std::shared_ptr m_impl; + DLL_WARNINGS_POP + bool m_end; + +public: + + Iterator& operator++(); + bool operator==(const Iterator&) const; + bool operator!=(const Iterator &other) const { return !(*this == other); } + const Field& operator*(); + + friend DbDoc; +}; + + +// Value class +// =========== + +/** + %Value object can store value of scalar type, string, array or document. + + Implicit conversions to and from corresponding C++ types are defined. + If conversion to wrong type is attempted, an error is thrown. If Value + object holds an array or document, then array elements or fields of + the document can be accessed using operator[]. Array values can be used + as STL containers. + + Only direct conversions of stored value to the corresponding C++ type + are supported. There are no implicit number->string conversions etc. + + Values of type RAW can refer to a region of memory containing raw bytes. + Such values are created from `bytes` and can by casted to `bytes` type. + + @note Value object copies the values it stores. Thus, after storing value + in Value object, the original value can be destroyed without invalidating + the copy. This includes RAW Values which hold a copy of bytes. + + @ingroup devapi_res +*/ + +class Value + : public virtual common::Printable + , protected common::Value +{ +public: + + using string = mysqlx::string; + + /** + Possible types of values. + + @sa getType() + */ + + enum Type + { + VNULL, ///< Null value + UINT64, ///< Unsigned integer + INT64, ///< Signed integer + FLOAT, ///< Float number + DOUBLE, ///< Double number + BOOL, ///< Boolean + STRING, ///< String + DOCUMENT, ///< Document + RAW, ///< Raw bytes + ARRAY, ///< Array of values + }; + + typedef std::vector::iterator iterator; + typedef std::vector::const_iterator const_iterator; + + ///@name Value Constructors + ///@{ + + Value(); ///< Constructs Null value. + Value(std::nullptr_t); ///< Constructs Null value. + + Value(const mysqlx::string &str); + Value(mysqlx::string &&str); + //Value(const char16_t *str) : Value(mysqlx::string(str)) {} + + Value(const std::string &str); + Value(std::string &&str); + Value(const char *str) : Value(std::string(str)) {} + + template + Value(const std::basic_string &str) + : Value(mysqlx::string(str)) + {} + + template + Value(const C *str) + : Value(mysqlx::string(str)) + {} + + Value(const bytes&); + Value(int64_t); + Value(uint64_t); + Value(float); + Value(double); + Value(bool); + Value(const DbDoc& doc); + + Value(const std::initializer_list &list); + template + Value(Iterator begin_, Iterator end_); + + ///@} + + Value(common::Value &&other); + Value(const common::Value &other); + + Value(const Value&) = default; + +#ifdef HAVE_MOVE_CTORS + + Value(Value&&) = default; + +#else + + // Note move ctor implemented using move assignment defined below. + + Value(Value &&other) + { + *this = std::move(other); + } + +#endif + + /* + Note: These templates are needed to disambiguate constructor resolution + for integer types. + */ + + template < + typename T, + typename std::enable_if::value>::type* = nullptr + > + Value(T x) + : Value(static_cast(x)) + {} + + template < + typename T, + typename std::enable_if::value>::type* = nullptr + > + Value(T x) + : Value(static_cast(x)) + {} + + + Value& operator=(const Value&) = default; + + /* + Note: Move assignment is defined explicitly to avoid problems with + virtual Printable base. + */ + + Value& operator=(Value&&); + + /* + Assignment is implemented in terms of constructors: first an instance + is created from the input data and then move assignment is used to place + the result into this instance. + */ + + template + Value& operator=(T&& x) + { + try { + *this = Value(std::forward(x)); + return *this; + } + CATCH_AND_WRAP + } + + +public: + + /** + @name Conversion to C++ Types + + Attempt to convert value of non-compatible type throws an error. + */ + //@{ + + operator int() const; + operator unsigned() const; + operator int64_t() const; + operator uint64_t() const; + + operator float() const; + operator double() const; + + explicit operator bool() const; + + operator mysqlx::string() const; + explicit operator std::string() const; + + template + explicit operator std::basic_string() const + { + return this->operator mysqlx::string(); + } + + explicit operator bytes() const; + operator DbDoc() const; + + + template + T get() const; + + //@} + + + bytes getRawBytes() const + { + try { + size_t len; + const byte *ptr = get_bytes(&len); + return { ptr, len }; + } + CATCH_AND_WRAP + } + + + /** + Return type of the value stored in this instance (or VNULL if no + value is stored). + */ + + Type getType() const; + + /// Convenience method for checking if value is null. + + bool isNull() const + { + return VNULL == getType(); + } + + /** + Check if document value contains given (top-level) field. + Throws error if this is not a document value. + */ + + bool hasField(const Field&) const; + + /** + If this value is not a document, throws error. Otherwise + returns value of given field of the document. + */ + + const Value& operator[](const Field&) const; + + const Value& operator[](const char *name) const + { return (*this)[Field(name)]; } + + const Value& operator[](const mysqlx::string &name) const + { return (*this)[Field(name)]; } + + + /** + Access to elements of an array value. + + If non-array value is accessed like an array, an error is thrown. + */ + //@{ + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + size_t elementCount() const; + + const Value& operator[](unsigned) const; + const Value& operator[](int pos) const + { + assert(pos >= 0); + return operator[]((unsigned)pos); + } + + //@} + + + /// Print the value to a stream. + + void print(std::ostream &out) const + { + switch (m_type) + { + case DOC: out << m_doc; return; + case ARR: + { + bool first = true; + out << "["; + for (auto it = m_arr->begin();it!=m_arr->end();++it) + { + if (!first) + { + out << ", "; + } + else + { + first = false; + } + + switch (it->get_type()) + { + case common::Value::STRING: + case common::Value::USTRING: + case common::Value::EXPR: + out << R"(")" << *it << R"(")"; + break; + default: + out << *it; + break; + } + + + } + out << "]"; + return; + } + default: common::Value::print(out); return; + } + } + +protected: + + enum { VAL, ARR, DOC } m_type = VAL; + + void check_type(Type t) const + { + if (getType() != t) + throw Error("Invalid value type"); + } + + bool is_expr() const + { + return VAL == m_type && common::Value::EXPR == common::Value::get_type(); + } + + void set_as_expr() + { + common::Value::m_type = common::Value::EXPR; + } + + /* + TODO: Instead extend common::Value with array and document types. Requires + moving DbDoc code to the common layer. + */ + + typedef std::vector Array; + + DLL_WARNINGS_PUSH + + DbDoc m_doc; + + // Note: shared with other Value instances for the same array. + std::shared_ptr m_arr; + + DLL_WARNINGS_POP + +public: + + friend SessionSettings; + friend DbDoc; + + ///@cond IGNORE + friend mysqlx::string; + ///@endcond IGNORE + + struct INTERNAL Access; + friend Access; +}; + +static const Value nullvalue; + + +inline +Value& Value::operator=(Value &&other) +{ + m_type = other.m_type; + + switch (m_type) + { + case VAL: + common::Value::operator=(std::move(other)); + break; + + case DOC: m_doc = std::move(other.m_doc); break; + case ARR: m_arr = std::move(other.m_arr); break; + + default: break; + } + + return *this; +} + + +namespace internal { + +/* + Helper class to identify usage of expressions +*/ + +class Expression + : public mysqlx::Value +{ + Expression() + {} + + template + Expression(V&& val) + : Value(std::forward(val)) + { + set_as_expr(); + } + + template + Expression(const V& val) + : Value(val) + { + set_as_expr(); + } + + friend Expression expr(std::string&& s); + friend Expression expr(const std::string& s); +}; + + +/** + Function which indicates that a given string should be treated + as expression. + + If `s` is a string value, then in contexts where values are + expected, `expr(s)` treats `s` as a DevAPI expression. For + example statement + + table.select("foo > 1").execute(); + + returns the string `"foo 1"` for each row in the table while + + table.select(expr("foo > 1")).execute(); + + returns true/false, depending on the value of the expression. + + @ingroup devapi +*/ + +inline +internal::Expression expr(std::string&& e) +{ + return std::forward(e); +} + +inline +internal::Expression expr(const std::string& e) +{ + return e; +} + +} // internal + + +using internal::expr; + + +inline +Value::Type Value::getType() const +{ + switch (m_type) + { + case ARR: return ARRAY; + case DOC: return DOCUMENT; + case VAL: + switch (common::Value::get_type()) + { + case common::Value::VNULL: return VNULL; + case common::Value::UINT64: return UINT64; + case common::Value::INT64: return INT64; + case common::Value::FLOAT: return FLOAT; + case common::Value::DOUBLE: return DOUBLE; + case common::Value::BOOL: return BOOL; + case common::Value::STRING: return STRING; + case common::Value::USTRING: return STRING; + case common::Value::RAW: return RAW; + case common::Value::EXPR: return STRING; + case common::Value::JSON: return DOCUMENT; + } + } + return VNULL; // quiet compiler warning +} + + +/* + Value type conversions + ---------------------- + TODO: more informative errors +*/ + + +inline +Value::Value(const std::initializer_list &list) + : m_type(ARR) +{ + try { + m_arr = std::make_shared(list); + } + CATCH_AND_WRAP +} + +template +inline +Value::Value(Iterator begin_, Iterator end_) + : m_type(ARR) +{ + try { + m_arr = std::make_shared(begin_, end_); + } + CATCH_AND_WRAP +} + + +inline +Value::Value(common::Value &&other) +try + : common::Value(std::move(other)) +{} +CATCH_AND_WRAP + +inline +Value::Value(const common::Value &other) +try + : common::Value(other) +{} +CATCH_AND_WRAP + + +inline Value::Value() +{} + +inline Value::Value(std::nullptr_t) +{} + +inline Value::Value(int64_t val) +try + : common::Value(val) +{} +CATCH_AND_WRAP + +inline Value::Value(uint64_t val) +try + : common::Value(val) +{} +CATCH_AND_WRAP + +template <> +PUBLIC_API common::Value Value::get() const; + +template<> +inline +int Value::get() const +{ + try { + int64_t val = get_sint(); + if (val > std::numeric_limits::max()) + throw Error("Numeric conversion overflow"); + if (val < std::numeric_limits::min()) + throw Error("Numeric conversion overflow"); + + return (int)val; + } + CATCH_AND_WRAP +} + +inline +Value::operator int() const +{ + return get(); +} + + +template<> +inline unsigned Value::get() const +{ + try { + uint64_t val = get_uint(); + if (val > std::numeric_limits::max()) + throw Error("Numeric conversion overflow"); + + return (unsigned)val; + } + CATCH_AND_WRAP +} + +inline +Value::operator unsigned() const +{ + return get(); +} + + +template<> +inline int64_t Value::get() const +{ + try { + return get_sint(); + } + CATCH_AND_WRAP +} + +inline +Value::operator int64_t() const +{ + return get(); +} + + +template<> +inline uint64_t Value::get() const +{ + try { + return get_uint(); + } + CATCH_AND_WRAP +} + +inline +Value::operator uint64_t() const +{ + return get(); +} + + +inline Value::Value(float val) +try + : common::Value(val) +{} +CATCH_AND_WRAP + +template<> +inline +float Value::get() const +{ + try { + return get_float(); + } + CATCH_AND_WRAP +} + +inline +Value::operator float() const +{ + return get(); +} + + +inline Value::Value(double val) +try + : common::Value(val) +{} +CATCH_AND_WRAP + +template<> +inline +double Value::get() const +{ + try { + return get_double(); + } + CATCH_AND_WRAP +} + +inline +Value::operator double() const +{ + return get(); +} + + +inline Value::Value(bool val) +try + : common::Value(val) +{} +CATCH_AND_WRAP + + +template<> +inline +bool Value::get() const +{ + try { + return get_bool(); + } + CATCH_AND_WRAP +} + +inline +Value::operator bool() const +{ + return get(); +} + + +inline Value::Value(const DbDoc &doc) +try + : m_type(DOC) + , m_doc(doc) +{} +CATCH_AND_WRAP + + + +inline Value::Value(const mysqlx::string &val) +try + : common::Value(val) +{} +CATCH_AND_WRAP + +inline Value::Value(mysqlx::string &&val) +try + : common::Value(std::move(val)) +{} +CATCH_AND_WRAP + + +inline Value::Value(const std::string &val) +try + : common::Value(val) +{} +CATCH_AND_WRAP + +inline Value::Value(std::string &&val) +try + : common::Value(std::move(val)) +{} +CATCH_AND_WRAP + + +template<> +inline +std::wstring Value::get() const +{ + try { + return mysqlx::string(this->get_ustring()); + } + CATCH_AND_WRAP +} + + +template<> +inline +std::string Value::get() const +{ + try { + return get_string(); + } + CATCH_AND_WRAP +} + +inline +Value::operator std::string() const +{ + return get(); +} + + +template<> +inline +mysqlx::string Value::get() const +{ + try { + return this->get_ustring(); + } + CATCH_AND_WRAP +} + +inline +Value::operator mysqlx::string() const +{ + return get(); +} + + +inline Value::Value(const bytes &data) +try + : common::Value(data.begin(), data.length()) +{} +CATCH_AND_WRAP + +template<> +inline +bytes Value::get() const +{ + return getRawBytes(); +} + +inline +Value::operator bytes() const +{ + return get(); +} + + +template<> +inline +DbDoc Value::get() const +{ + check_type(DOCUMENT); + return m_doc; +} + +inline +Value::operator DbDoc() const +{ + return get(); +} + + +inline +bool Value::hasField(const Field &fld) const +{ + check_type(DOCUMENT); + return m_doc.hasField(fld); +} + +inline +const Value& Value::operator[](const Field &fld) const +{ + check_type(DOCUMENT); + return m_doc[fld]; +} + +inline +int DbDoc::fieldType(const Field &fld) const +{ + return (*this)[fld].getType(); +} + +// Array access + + +inline +Value::iterator Value::begin() +{ + if (ARR != m_type) + throw Error("Attempt to iterate over non-array value"); + return m_arr->begin(); +} + +inline +Value::const_iterator Value::begin() const +{ + if (ARR != m_type) + throw Error("Attempt to iterate over non-array value"); + return m_arr->begin(); +} + +inline +Value::iterator Value::end() +{ + if (ARR != m_type) + throw Error("Attempt to iterate over non-array value"); + return m_arr->end(); +} + +inline +Value::const_iterator Value::end() const +{ + if (ARR != m_type) + throw Error("Attempt to iterate over non-array value"); + return m_arr->end(); +} + +inline +const Value& Value::operator[](unsigned pos) const +{ + check_type(ARRAY); + return m_arr->at(pos); +} + +inline +size_t Value::elementCount() const +{ + check_type(ARRAY); + return m_arr->size(); +} + + +MYSQLX_ABI_END(2,0) +} // mysqlx + + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/error.h b/Libraries/mysql-connector/include/mysqlx/devapi/error.h new file mode 100644 index 0000000..17835d1 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/error.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_ERROR_H +#define MYSQLX_ERROR_H + +/** + @file + Classes used to access query and command execution results. +*/ + + +#include "common.h" +#include "detail/error.h" + +#include + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +/** + An error, warning or other diagnostic information reported by server + when executing queries or statements. The information can be printed to + output stream using `<<` operator. + + @note Normally, errors reported by server are not represented by `Warning` + instances but instead they are thrown as instances of `mysqlx::Error`. + + @ingroup devapi +*/ + +class Warning + : public virtual common::Printable + , internal::Warning_detail +{ +public: + + /// Type of diagnostic information. + + enum Level { + LEVEL_ERROR, ///< %Error + LEVEL_WARNING, ///< %Warning + LEVEL_INFO ///< Other information + }; + +private: + + Warning(Level level, uint16_t code, const string &msg) + : Warning_detail(byte(level), code, msg) + { + } + + Warning(Warning_detail &&init) + : Warning_detail(std::move(init)) + {} + + void print(std::ostream &out) const + { + try { + Warning_detail::print(out); + } + CATCH_AND_WRAP + } + +public: + + /** + Return level of the diagnostic info stored in this object. + */ + + Level getLevel() const + { + return Level(m_level); + } + + /** + Return error/warning code reported by server. + */ + + uint16_t getCode() const + { + return m_code; + } + + /** + Return diagnostic message reported by server. + */ + + const string& getMessage() const + { + return m_msg; + } + + + ///@cond IGNORE + friend internal::Result_detail; + ///@endcond + + struct Access; + friend Access; +}; + + +inline +void internal::Warning_detail::print(std::ostream &out) const +{ + switch (Warning::Level(m_level)) + { + case Warning::LEVEL_ERROR: out << "Error"; break; + case Warning::LEVEL_WARNING: out << "Warning"; break; + case Warning::LEVEL_INFO: out << "Info"; break; + default: out << ""; break; + } + + if (m_code) + out << " " << m_code; + + out << ": " << m_msg; +} + + +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/executable.h b/Libraries/mysql-connector/include/mysqlx/devapi/executable.h new file mode 100644 index 0000000..22f7e76 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/executable.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_EXECUTABLE_H +#define MYSQLX_EXECUTABLE_H + +/** + @file + Class representing executable statements. +*/ + + +#include "common.h" +#include "result.h" +#include "../common/op_if.h" + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +using std::ostream; + + +/** + Represents an operation that can be executed. + + Creating an operation does not involve any communication with the server. + Only when `execute()` method is called operation is sent to the server + for execution. + + The template parameter `Res` is the type of result that + is returned by `execute()` method. + + A derived class must create an implementation object for the operation and + set it using reset() method. Such implementation object should implement + common::Executable_if interface. +*/ + +template +class Executable +{ +private: + using Impl = common::Executable_if; + + std::unique_ptr m_impl; +protected: + + + Executable() = default; + + void reset(Impl *impl) + { + m_impl.reset(impl); + } + + /* + Copy semantics implementation: the current state of the other executable + object (of its implementation, to be precise) is copied to this new + instance. After that the two executables are independent objects describing + the same operation. + */ + + void reset(const Executable &other) + { + if (m_impl.get() != other.m_impl.get()) m_impl.reset(other.m_impl->clone()); + } + + void reset(const Executable &&other) + { + m_impl.reset(other.m_impl->clone()); + } + + void check_if_valid() const + { + if (!m_impl) + throw Error("Attempt to use invalid operation"); + } + + Impl* get_impl() + { + check_if_valid(); + return m_impl.get(); + } + +public: + + Executable(const Executable &other) + { + operator=(other); + } + + Executable(Executable &&other) + { + operator=(std::move(other)); + } + + virtual ~Executable() {} + + + Executable& operator=(const Executable &other) + { + try { + reset(other); + return *this; + } + CATCH_AND_WRAP + } + + Executable& operator=(Executable &&other) + { + try { + reset(std::move(other)); + return *this; + } + CATCH_AND_WRAP + } + + + /// Execute given operation and return its result. + + virtual Res execute() + { + try { + check_if_valid(); + /* + Note: The implementation object's execute() methods returns a reference + to a common::Result_init object which provides information about + the session and pending server reply. The returned Res instance should + be constructible from such Result_init reference. + */ + return m_impl->execute(); + } + CATCH_AND_WRAP + } + + struct Access; + friend Access; +}; + + +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/mysql_charsets.h b/Libraries/mysql-connector/include/mysqlx/devapi/mysql_charsets.h new file mode 100644 index 0000000..c4c0d1d --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/mysql_charsets.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +/* + Lists of character sets known to CDK string codec (see codec.h). + + Note: Keep this file in sync with +*/ + + +#ifndef MYSQLX_MYSQL_CHARSETS_H +#define MYSQLX_MYSQL_CHARSETS_H + +#define CDK_CS_LIST(X) \ + X(big5) \ + X(dec8) \ + X(cp850) \ + X(hp8) \ + X(koi8r) \ + X(latin1) \ + X(latin2) \ + X(swe7) \ + X(ascii) \ + X(ujis) \ + X(sjis) \ + X(hebrew) \ + X(tis620) \ + X(euckr) \ + X(koi8u) \ + X(gb2312) \ + X(greek) \ + X(cp1250) \ + X(gbk) \ + X(latin5) \ + X(armscii8) \ + X(utf8mb3) \ + X(ucs2) \ + X(cp866) \ + X(keybcs2) \ + X(macce) \ + X(macroman) \ + X(cp852) \ + X(latin7) \ + X(utf8mb4) \ + X(cp1251) \ + X(utf16) \ + X(utf16le) \ + X(cp1256) \ + X(cp1257) \ + X(utf32) \ + X(binary) \ + X(geostd8) \ + X(cp932) \ + X(eucjpms) \ + X(gb18030) \ + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/mysql_collations.h b/Libraries/mysql-connector/include/mysqlx/devapi/mysql_collations.h new file mode 100644 index 0000000..9ea06ab --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/mysql_collations.h @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + Lists of collations used by MySQL Server and its protocols. These lists + define mapping from MySQL collation ID to charset ID. + + Note: Keep this file in sync with +*/ + +#ifndef MYSQLX_MYSQL_COLLATIONS_H +#define MYSQLX_MYSQL_COLLATIONS_H + +/* + Each line X(CS, ID, COLL, SENSITIVITY) in the expansion of + a COLLATION_XXX() macro declares collation with name COLL for character set + CS. ID is the MySQL id number for the collation. SENSITIVITY is either 'bin' + for binary collations or a combination of sensitivity flags such as 'ai_ci', + using the same conventions as the ones used in MySQL collation names. + + Note: CS, COLL and SENSITIVITY are used to reconstruct the full MySQL name of + the collation and should follow the same naming conventions (with few + exceptions that we handle separately) +*/ + + +#define COLLATIONS_big5(X) \ + X(big5,1,chinese,ci) \ + X(big5,84,bin,bin) \ + +#define COLLATIONS_dec8(X) \ + X(dec8,3,swedish,ci) \ + X(dec8,69,bin,bin) \ + +#define COLLATIONS_cp850(X) \ + X(cp850,4,general,ci) \ + X(cp850,80,bin,bin) \ + +#define COLLATIONS_hp8(X) \ + X(hp8,6,english,ci) \ + X(hp8,72,bin,bin) \ + +#define COLLATIONS_koi8r(X) \ + X(koi8r,7,general,ci) \ + X(koi8r,74,bin,bin) \ + +#define COLLATIONS_latin1(X) \ + X(latin1,5,german1,ci) \ + X(latin1,8,swedish,ci) \ + X(latin1,15,danish,ci) \ + X(latin1,31,german2,ci) \ + X(latin1,47,bin,bin) \ + X(latin1,48,general,ci) \ + X(latin1,49,general,cs) \ + X(latin1,94,spanish,ci) \ + +#define COLLATIONS_latin2(X) \ + X(latin2,2,czech,cs) \ + X(latin2,9,general,ci) \ + X(latin2,21,hungarian,ci) \ + X(latin2,27,croatian,ci) \ + X(latin2,77,bin,bin) \ + +#define COLLATIONS_swe7(X) \ + X(swe7,10,swedish,ci) \ + X(swe7,82,bin,bin) \ + +#define COLLATIONS_ascii(X) \ + X(ascii,11,general,ci) \ + X(ascii,65,bin,bin) \ + +#define COLLATIONS_ujis(X) \ + X(ujis,12,japanese,ci) \ + X(ujis,91,bin,bin) \ + +#define COLLATIONS_sjis(X) \ + X(sjis,13,japanese,ci) \ + X(sjis,88,bin,bin) \ + +#define COLLATIONS_hebrew(X) \ + X(hebrew,16,general,ci) \ + X(hebrew,71,bin,bin) \ + +#define COLLATIONS_tis620(X) \ + X(tis620,18,thai,ci) \ + X(tis620,89,bin,bin) \ + +#define COLLATIONS_euckr(X) \ + X(euckr,19,korean,ci) \ + X(euckr,85,bin,bin) \ + +#define COLLATIONS_koi8u(X) \ + X(koi8u,22,general,ci) \ + X(koi8u,75,bin,bin) \ + +#define COLLATIONS_gb2312(X) \ + X(gb2312,24,chinese,ci) \ + X(gb2312,86,bin,bin) \ + +#define COLLATIONS_greek(X) \ + X(greek,25,general,ci) \ + X(greek,70,bin,bin) \ + +#define COLLATIONS_cp1250(X) \ + X(cp1250,26,general,ci) \ + X(cp1250,34,czech,cs) \ + X(cp1250,44,croatian,ci) \ + X(cp1250,66,bin,bin) \ + X(cp1250,99,polish,ci) \ + +#define COLLATIONS_gbk(X) \ + X(gbk,28,chinese,ci) \ + X(gbk,87,bin,bin) \ + +#define COLLATIONS_latin5(X) \ + X(latin5,30,turkish,ci) \ + X(latin5,78,bin,bin) \ + +#define COLLATIONS_armscii8(X) \ + X(armscii8,32,general,ci) \ + X(armscii8,64,bin,bin) \ + +#define COLLATIONS_utf8mb3(X) \ + X(utf8mb3,33,general,ci) \ + X(utf8mb3,76,tolower,ci) \ + X(utf8mb3,83,bin,bin) \ + X(utf8mb3,192,unicode,ci) \ + X(utf8mb3,193,icelandic,ci) \ + X(utf8mb3,194,latvian,ci) \ + X(utf8mb3,195,romanian,ci) \ + X(utf8mb3,196,slovenian,ci) \ + X(utf8mb3,197,polish,ci) \ + X(utf8mb3,198,estonian,ci) \ + X(utf8mb3,199,spanish,ci) \ + X(utf8mb3,200,swedish,ci) \ + X(utf8mb3,201,turkish,ci) \ + X(utf8mb3,202,czech,ci) \ + X(utf8mb3,203,danish,ci) \ + X(utf8mb3,204,lithuanian,ci) \ + X(utf8mb3,205,slovak,ci) \ + X(utf8mb3,206,spanish2,ci) \ + X(utf8mb3,207,roman,ci) \ + X(utf8mb3,208,persian,ci) \ + X(utf8mb3,209,esperanto,ci) \ + X(utf8mb3,210,hungarian,ci) \ + X(utf8mb3,211,sinhala,ci) \ + X(utf8mb3,212,german2,ci) \ + X(utf8mb3,213,croatian,ci) \ + X(utf8mb3,214,unicode_520,ci) \ + X(utf8mb3,215,vietnamese,ci) \ + X(utf8mb3,223,general_mysql500,ci) \ + +#define COLLATIONS_ucs2(X) \ + X(ucs2,35,general,ci) \ + X(ucs2,90,bin,bin) \ + X(ucs2,128,unicode,ci) \ + X(ucs2,129,icelandic,ci) \ + X(ucs2,130,latvian,ci) \ + X(ucs2,131,romanian,ci) \ + X(ucs2,132,slovenian,ci) \ + X(ucs2,133,polish,ci) \ + X(ucs2,134,estonian,ci) \ + X(ucs2,135,spanish,ci) \ + X(ucs2,136,swedish,ci) \ + X(ucs2,137,turkish,ci) \ + X(ucs2,138,czech,ci) \ + X(ucs2,139,danish,ci) \ + X(ucs2,140,lithuanian,ci) \ + X(ucs2,141,slovak,ci) \ + X(ucs2,142,spanish2,ci) \ + X(ucs2,143,roman,ci) \ + X(ucs2,144,persian,ci) \ + X(ucs2,145,esperanto,ci) \ + X(ucs2,146,hungarian,ci) \ + X(ucs2,147,sinhala,ci) \ + X(ucs2,148,german2,ci) \ + X(ucs2,149,croatian,ci) \ + X(ucs2,150,unicode_520,ci) \ + X(ucs2,151,vietnamese,ci) \ + X(ucs2,159,general_mysql500,ci) \ + +#define COLLATIONS_cp866(X) \ + X(cp866,36,general,ci) \ + X(cp866,68,bin,bin) \ + +#define COLLATIONS_keybcs2(X) \ + X(keybcs2,37,general,ci) \ + X(keybcs2,73,bin,bin) \ + +#define COLLATIONS_macce(X) \ + X(macce,38,general,ci) \ + X(macce,43,bin,bin) \ + +#define COLLATIONS_macroman(X) \ + X(macroman,39,general,ci) \ + X(macroman,53,bin,bin) \ + +#define COLLATIONS_cp852(X) \ + X(cp852,40,general,ci) \ + X(cp852,81,bin,bin) \ + +#define COLLATIONS_latin7(X) \ + X(latin7,20,estonian,cs) \ + X(latin7,41,general,ci) \ + X(latin7,42,general,cs) \ + X(latin7,79,bin,bin) \ + +#define COLLATIONS_utf8mb4(X) \ + X(utf8mb4,255,uca0900,ai_ci) \ + X(utf8mb4,278,uca0900,as_cs) \ + X(utf8mb4,46,bin,bin) \ + X(utf8mb4,245,croatian,ci) \ + X(utf8mb4,266,cs_0900,ai_ci) \ + X(utf8mb4,289,cs_0900,as_cs) \ + X(utf8mb4,234,czech,ci) \ + X(utf8mb4,235,danish,ci) \ + X(utf8mb4,267,da_0900,ai_ci) \ + X(utf8mb4,290,da_0900,as_cs) \ + X(utf8mb4,256,de_pb_0900,ai_ci) \ + X(utf8mb4,279,de_pb_0900,as_cs) \ + X(utf8mb4,273,eo_0900,ai_ci) \ + X(utf8mb4,296,eo_0900,as_cs) \ + X(utf8mb4,241,esperanto,ci) \ + X(utf8mb4,230,estonian,ci) \ + X(utf8mb4,263,es_0900,ai_ci) \ + X(utf8mb4,286,es_0900,as_cs) \ + X(utf8mb4,270,es_trad_0900,ai_ci) \ + X(utf8mb4,293,es_trad_0900,as_cs) \ + X(utf8mb4,262,et_0900,ai_ci) \ + X(utf8mb4,285,et_0900,as_cs) \ + X(utf8mb4,45,general,ci) \ + X(utf8mb4,244,german2,ci) \ + X(utf8mb4,275,hr_0900,ai_ci) \ + X(utf8mb4,298,hr_0900,as_cs) \ + X(utf8mb4,242,hungarian,ci) \ + X(utf8mb4,274,hu_0900,ai_ci) \ + X(utf8mb4,297,hu_0900,as_cs) \ + X(utf8mb4,225,icelandic,ci) \ + X(utf8mb4,257,is_0900,ai_ci) \ + X(utf8mb4,280,is_0900,as_cs) \ + X(utf8mb4,303,ja_0900,as_cs) \ + X(utf8mb4,226,latvian,ci) \ + X(utf8mb4,271,la_0900,ai_ci) \ + X(utf8mb4,294,la_0900,as_cs) \ + X(utf8mb4,236,lithuanian,ci) \ + X(utf8mb4,268,lt_0900,ai_ci) \ + X(utf8mb4,291,lt_0900,as_cs) \ + X(utf8mb4,258,lv_0900,ai_ci) \ + X(utf8mb4,281,lv_0900,as_cs) \ + X(utf8mb4,240,persian,ci) \ + X(utf8mb4,261,pl_0900,ai_ci) \ + X(utf8mb4,284,pl_0900,as_cs) \ + X(utf8mb4,229,polish,ci) \ + X(utf8mb4,227,romanian,ci) \ + X(utf8mb4,239,roman,ci) \ + X(utf8mb4,259,ro_0900,ai_ci) \ + X(utf8mb4,282,ro_0900,as_cs) \ + X(utf8mb4,243,sinhala,ci) \ + X(utf8mb4,269,sk_0900,ai_ci) \ + X(utf8mb4,292,sk_0900,as_cs) \ + X(utf8mb4,237,slovak,ci) \ + X(utf8mb4,228,slovenian,ci) \ + X(utf8mb4,260,sl_0900,ai_ci) \ + X(utf8mb4,283,sl_0900,as_cs) \ + X(utf8mb4,238,spanish2,ci) \ + X(utf8mb4,231,spanish,ci) \ + X(utf8mb4,264,sv_0900,ai_ci) \ + X(utf8mb4,287,sv_0900,as_cs) \ + X(utf8mb4,232,swedish,ci) \ + X(utf8mb4,265,tr_0900,ai_ci) \ + X(utf8mb4,288,tr_0900,as_cs) \ + X(utf8mb4,233,turkish,ci) \ + X(utf8mb4,246,unicode_520,ci) \ + X(utf8mb4,224,unicode,ci) \ + X(utf8mb4,247,vietnamese,ci) \ + X(utf8mb4,277,vi_0900,ai_ci) \ + X(utf8mb4,300,vi_0900,as_cs) \ + X(utf8mb4,304,ja_0900,as_cs_ks) \ + X(utf8mb4,305,uca0900,as_ci) \ + X(utf8mb4,306,ru_0900,ai_ci) \ + X(utf8mb4,307,ru_0900,as_cs) \ + X(utf8mb4,308,zh_0900,as_cs) \ + X(utf8mb4,309,uca0900,bin) \ + X(utf8mb4,310,nb_0900,ai_ci) \ + X(utf8mb4,311,nb_0900,as_cs) \ + X(utf8mb4,312,nn_0900,ai_ci) \ + X(utf8mb4,313,nn_0900,as_cs) \ + X(utf8mb4,314,sr_latn_0900,ai_ci) \ + X(utf8mb4,315,sr_latn_0900,as_cs) \ + X(utf8mb4,316,bs_0900,ai_ci) \ + X(utf8mb4,317,bs_0900,as_cs) \ + X(utf8mb4,318,bg_0900,ai_ci) \ + X(utf8mb4,319,bg_0900,as_cs) \ + X(utf8mb4,320,gl_0900,ai_ci) \ + X(utf8mb4,321,gl_0900,as_cs) \ + X(utf8mb4,322,mn_cyrl_0900,ai_ci) \ + X(utf8mb4,323,mn_cyrl_0900,as_cs) \ + COLLATIONS_utf8mb4_EXTRA + +#define COLLATIONS_utf8mb4_EXTRA + + +#define COLLATIONS_cp1251(X) \ + X(cp1251,14,bulgarian,ci) \ + X(cp1251,23,ukrainian,ci) \ + X(cp1251,50,bin,bin) \ + X(cp1251,51,general,ci) \ + X(cp1251,52,general,cs) \ + +#define COLLATIONS_utf16(X) \ + X(utf16,54,general,ci) \ + X(utf16,55,bin,bin) \ + X(utf16,101,unicode,ci) \ + X(utf16,102,icelandic,ci) \ + X(utf16,103,latvian,ci) \ + X(utf16,104,romanian,ci) \ + X(utf16,105,slovenian,ci) \ + X(utf16,106,polish,ci) \ + X(utf16,107,estonian,ci) \ + X(utf16,108,spanish,ci) \ + X(utf16,109,swedish,ci) \ + X(utf16,110,turkish,ci) \ + X(utf16,111,czech,ci) \ + X(utf16,112,danish,ci) \ + X(utf16,113,lithuanian,ci) \ + X(utf16,114,slovak,ci) \ + X(utf16,115,spanish2,ci) \ + X(utf16,116,roman,ci) \ + X(utf16,117,persian,ci) \ + X(utf16,118,esperanto,ci) \ + X(utf16,119,hungarian,ci) \ + X(utf16,120,sinhala,ci) \ + X(utf16,121,german2,ci) \ + X(utf16,122,croatian,ci) \ + X(utf16,123,unicode_520,ci) \ + X(utf16,124,vietnamese,ci) \ + +#define COLLATIONS_utf16le(X) \ + X(utf16le,56,general,ci) \ + X(utf16le,62,bin,bin) \ + +#define COLLATIONS_cp1256(X) \ + X(cp1256,57,general,ci) \ + X(cp1256,67,bin,bin) \ + +#define COLLATIONS_cp1257(X) \ + X(cp1257,29,lithuanian,ci) \ + X(cp1257,58,bin,bin) \ + X(cp1257,59,general,ci) \ + +#define COLLATIONS_utf32(X) \ + X(utf32,60,general,ci) \ + X(utf32,61,bin,bin) \ + X(utf32,160,unicode,ci) \ + X(utf32,161,icelandic,ci) \ + X(utf32,162,latvian,ci) \ + X(utf32,163,romanian,ci) \ + X(utf32,164,slovenian,ci) \ + X(utf32,165,polish,ci) \ + X(utf32,166,estonian,ci) \ + X(utf32,167,spanish,ci) \ + X(utf32,168,swedish,ci) \ + X(utf32,169,turkish,ci) \ + X(utf32,170,czech,ci) \ + X(utf32,171,danish,ci) \ + X(utf32,172,lithuanian,ci) \ + X(utf32,173,slovak,ci) \ + X(utf32,174,spanish2,ci) \ + X(utf32,175,roman,ci) \ + X(utf32,176,persian,ci) \ + X(utf32,177,esperanto,ci) \ + X(utf32,178,hungarian,ci) \ + X(utf32,179,sinhala,ci) \ + X(utf32,180,german2,ci) \ + X(utf32,181,croatian,ci) \ + X(utf32,182,unicode_520,ci) \ + X(utf32,183,vietnamese,ci) \ + +#define COLLATIONS_binary(X) \ + X(binary,63,bin,bin) \ + +#define COLLATIONS_geostd8(X) \ + X(geostd8,92,general,ci) \ + X(geostd8,93,bin,bin) \ + +#define COLLATIONS_cp932(X) \ + X(cp932,95,japanese,ci) \ + X(cp932,96,bin,bin) \ + +#define COLLATIONS_eucjpms(X) \ + X(eucjpms,97,japanese,ci) \ + X(eucjpms,98,bin,bin) \ + +#define COLLATIONS_gb18030(X) \ + X(gb18030,248,chinese,ci) \ + X(gb18030,249,bin,bin) \ + X(gb18030,250,unicode_520,ci) \ + + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/result.h b/Libraries/mysql-connector/include/mysqlx/devapi/result.h new file mode 100644 index 0000000..3c9e4f9 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/result.h @@ -0,0 +1,908 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_RESULT_H +#define MYSQLX_RESULT_H + +/** + @file + Classes used to access query and command execution results. +*/ + +#include "common.h" +#include "document.h" +#include "row.h" +#include "collations.h" +#include "detail/result.h" + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +using std::ostream; + +class Session; +class Schema; +class Collection; +class Result; +class Row; +class RowResult; +class SqlResult; +class DbDoc; +class DocResult; + +template class Executable; + + +namespace internal { + +/* + A wrapper which adds methods common for all result classes. +*/ + +template +class Result_common + : protected Base +{ + using WarningList = internal::Result_detail::WarningList; + +public: + + /// Get the number of warnings stored in the result. + + unsigned getWarningsCount() const + { + try { + return Base::get_warning_count(); + } + CATCH_AND_WRAP + } + + /// Get a list of warnings stored in the result. + + WarningList getWarnings() + { + try { + return Base::get_warnings(); + } + CATCH_AND_WRAP + } + + /// Get the warning at the given, 0-based position. + // TODO: Change arg type to size_t? + + Warning getWarning(unsigned pos) + { + try { + return Base::get_warning(pos); + } + CATCH_AND_WRAP + } + + // TODO: expose this in the API? + //using WarningsIterator = Result_detail::iterator; + + /** + Get the count of affected items (rows or doucuments) from manipulation statements. + */ + + uint64_t getAffectedItemsCount() const + { + try { + return Result_detail::get_affected_rows(); + } CATCH_AND_WRAP + } + +protected: + + // Wrap base ctors/assginment with catch handlers + + Result_common() + try + : Base() + {} + CATCH_AND_WRAP + + Result_common(Result_common &&other) + try + : Base(std::move(other)) + {} + CATCH_AND_WRAP + + Result_common& operator=(Result_common &&other) + try + { + Base::operator=(std::move(other)); + return *this; + } + CATCH_AND_WRAP + + Result_common(common::Result_init &init) + try + : Base(init) + {} + CATCH_AND_WRAP + +}; + +} // internal namespace + + +/** + Represents a result of an operation that does not return data. + + A generic result which can be returned by operations which only + modify data. + + A `Result` instance can store the result of executing an operation: + + ~~~~~~ + Result res = operation.execute(); + ~~~~~~ + + Storing another result in a `Result` instance overwrites + the previous result. + + @note A `Result` object should be used by at most one thread at a time. It is + not safe to call its methods by several threads simultaneously. It is + responsibility of the user to ensure this using a synchronization mechanism + such as mutexes. + + + @ingroup devapi_res +*/ + +class Result + : public internal::Result_common +{ + +public: + + Result() = default; + + /** + Get the auto-increment value if one was generated by a table insert + statement. + */ + + uint64_t getAutoIncrementValue() const + { + try { + return Result_detail::get_auto_increment(); + } CATCH_AND_WRAP + } + + + /** + Return a list of identifiers of multiple documents added to a collection, + generated by the server. + */ + + DocIdList getGeneratedIds() const + { + try { + return Result_detail::get_generated_ids(); + } CATCH_AND_WRAP + } + +private: + + + Result(common::Result_init &init) + : Result_common(init) + {} + + template + friend class Executable; + friend Collection; +}; + + +// Row based results +// ----------------- + +/** + Types that can be reported in result meta-data. + + These correspond to MySQL server datatypes described [here] + (https://dev.mysql.com/doc/refman/8.0/en/data-types.html). + + @ingroup devapi_res +*/ + +enum class Type : unsigned short +{ +#undef TYPE_ENUM +#define TYPE_ENUM(X,N) X=N, + + RESULT_TYPE_LIST(TYPE_ENUM) +}; + +/* + Note: Normally we would put these docs in the RESULT_TYPE_LIST macro + but it would pollute documentation of methods like typeName() below + that also use this macro. +*/ + +/// @var Type::BIT +/// See +/// @var Type::TINYINT +/// See +/// @var Type::SMALLINT +/// See +/// @var Type::MEDIUMINT +/// See +/// @var Type::INT +/// See +/// @var Type::BIGINT +/// See +/// @var Type::FLOAT +/// See +/// @var Type::DECIMAL +/// See +/// @var Type::DOUBLE +/// See +/// @var Type::JSON +/// See +/// @var Type::STRING +/// See +/// @var Type::BYTES +/// See +/// @var Type::TIME +/// See +/// @var Type::DATE +/// See +/// @var Type::DATETIME +/// See +/// @var Type::TIMESTAMP +/// See +/// @var Type::SET +/// See +/// @var Type::ENUM +/// See +/// @var Type::GEOMETRY +/// See + + +/** + Return name of a given type. + + @ingroup devapi_res +*/ + +inline +const char* typeName(Type t) +{ +#define TYPE_NAME(T,X) case Type::T: return #T; + + switch (t) + { + RESULT_TYPE_LIST(TYPE_NAME) + default: + THROW("Unknown type"); + } +} + +inline +std::ostream& operator<<(std::ostream &out, Type t) +{ + return out << typeName(t); +} + + +/** + Provides meta-data for a single result column. + + @ingroup devapi_res +*/ + +class Column + : public virtual common::Printable + , private internal::Column_detail +{ +public: + + string getSchemaName() const ///< TODO + { + try { + return Column_detail::get_schema_name(); + } + CATCH_AND_WRAP + } + + string getTableName() const ///< TODO + { + try { + return Column_detail::get_table_name(); + } + CATCH_AND_WRAP + } + + string getTableLabel() const ///< TODO + { + try { + return Column_detail::get_table_label(); + } + CATCH_AND_WRAP + } + + string getColumnName() const ///< TODO + { + try { + return Column_detail::get_name(); + } + CATCH_AND_WRAP + } + + string getColumnLabel() const ///< TODO + { + try { + return Column_detail::get_label(); + } + CATCH_AND_WRAP + } + + Type getType() const ///< TODO + { + try { + return Type(Column_detail::get_type()); + } + CATCH_AND_WRAP + } + + /** + Get column length + + @return The maximum length of data in the column in bytes, as reported + by the server. + + @note Because the column length is returned as byte length, it could be + confusing with the multi-byte character sets. For instance, with UTF8MB4 + the length of VARCHAR(100) column is reported as 400 because each character + is 4 bytes long. + */ + + unsigned long getLength() const + { + try { + return Column_detail::get_length(); + } + CATCH_AND_WRAP + } + + unsigned short getFractionalDigits() const ///< TODO + { + try { + return Column_detail::get_decimals(); + } + CATCH_AND_WRAP + } + + bool isNumberSigned() const ///< TODO + { + try { + return Column_detail::is_signed(); + } + CATCH_AND_WRAP + } + + CharacterSet getCharacterSet() const ///< TODO + { + try { + return Column_detail::get_charset(); + } + CATCH_AND_WRAP + } + + /// TODO + std::string getCharacterSetName() const + { + try { + return characterSetName(getCharacterSet()); + } + CATCH_AND_WRAP + } + + const CollationInfo& getCollation() const ///< TODO + { + try { + return Column_detail::get_collation(); + } + CATCH_AND_WRAP + } + + /// TODO + std::string getCollationName() const + { + try { + return getCollation().getName(); + } + CATCH_AND_WRAP + } + + /// TODO + bool isPadded() const + { + try { + return Column_detail::is_padded(); + } + CATCH_AND_WRAP + } + +protected: + + + using Column_detail::Impl; + + Column(const Impl *impl) + try + : Column_detail(impl) + {} + CATCH_AND_WRAP + + Column() = default; + Column(const Column&) = default; + Column(Column&&) = default; + + Column& operator=(const Column&) = default; + + void print(std::ostream &out) const + { + // TODO: not sure if this code will be called by operator<<. + try { + Column_detail::print(out); + } + CATCH_AND_WRAP + } + +public: + + friend RowResult; + struct INTERNAL Access; + friend Access; +}; + + +/* + Extern declarations for Columns_detail template specialization + elements that are defined in result.cc. + + Note: "extern template" works with MSVC but not with GCC. +*/ + +namespace internal { + +template<> PUBLIC_API +void Columns_detail::init(const Result_detail::Impl&); + +} // internal + + +extern template PUBLIC_API +void internal::Columns_detail::init( + const internal::Result_detail::Impl &impl +); + + +class Columns + : private internal::Columns_detail +{ +public: + + using Columns_detail::operator[]; + + using Columns_detail::iterator; + + using Columns_detail::begin; + using Columns_detail::end; + +private: + + using Columns_detail::init; + + // note: Required by Row_result_detail + + Columns() = default; + Columns(Columns&&) = default; + Columns& operator=(Columns&&) = default; + + ///@cond IGNORE + friend internal::Row_result_detail; + ///@endcond +}; + + +/* + Extern declarations for Row_result_detail template specialization + elements that are defined in result.cc. +*/ + +namespace internal { + +template<> PUBLIC_API +bool Row_result_detail::iterator_next(); + +template<> PUBLIC_API +col_count_t Row_result_detail::col_count() const; + +template<> PUBLIC_API +Row_result_detail::Row_result_detail( + common::Result_init &init +); + +template<> PUBLIC_API +auto Row_result_detail::get_column(col_count_t pos) const +-> const Column&; + +template<> PUBLIC_API +auto internal::Row_result_detail::get_columns() const +-> const Columns&; + +template<> PUBLIC_API +row_count_t internal::Row_result_detail::row_count(); + +} // internal + + +/** + %Result of an operation that returns rows. + + A `RowResult` object gives sequential access to the rows contained in + the result. It is possible to get the rows one-by-one, or fetch and store + all of them at once. One can iterate over the rows using range loop: + `for (Row r : result) ...`. + + @ingroup devapi_res +*/ + +class RowResult + : public internal::Result_common> +{ +public: + + using Columns = mysqlx::Columns; + + RowResult() = default; + + + /// Return the number of fields in each row. + + col_count_t getColumnCount() const + { + try { + return Row_result_detail::col_count(); + } + CATCH_AND_WRAP + } + + /// Return `Column` object describing the given column of the result. + + const Column& getColumn(col_count_t pos) const + { + try { + return Row_result_detail::get_column(pos); + } + CATCH_AND_WRAP + } + + /** + Return meta-data for all result columns. + + TODO: explain ownership + */ + + const Columns& getColumns() const + { + try { + return Row_result_detail::get_columns(); + } + CATCH_AND_WRAP + } + + /** + Return the current row and move to the next one in the sequence. + + If there are no more rows in this result, returns a null `Row` instance. + */ + + Row fetchOne() + { + try { + return Row_result_detail::get_row(); + } + CATCH_AND_WRAP + } + + /** + Return all remaining rows + + %Result of this method can be stored in a container such as + `std::list`. Rows that have already been fetched using `fetchOne()` are + not included in the result of `fetchAll()`. + */ + + RowList fetchAll() + { + try { + return Row_result_detail::get_rows(); + } + CATCH_AND_WRAP + } + + /** + Returns the number of rows contained in the result. + + The method counts only the rows that were not yet fetched and are still + available in the result. + */ + + row_count_t count() + { + try { + return Row_result_detail::row_count(); + } + CATCH_AND_WRAP + } + + /* + Iterate over rows (range-for support). + + Rows that have been fetched using iterator are not available when + calling fetchOne() or fetchAll() + */ + + iterator begin() + { + try { + return Row_result_detail::begin(); + } + CATCH_AND_WRAP + } + + iterator end() const + { + try { + return Row_result_detail::end(); + } + CATCH_AND_WRAP + } + + +private: + + RowResult(common::Result_init &init) + : Result_common(init) + {} + +public: + + template friend class Executable; + friend SqlResult; + friend DocResult; +}; + + +/** + %Result of an SQL query or command. + + In general, an SQL query or command can return multiple results (for example, + a call to a stored procedure). Additionally, each or only some of these + results can contain row data. A `SqlResult` object gives a sequential access + to all results of a multi-result. Method `nextResult()` moves to the next + result in the sequence, if present. Methods of `RowResult` are used to access + row data of the current result (if it contains data). + + @note A `SqlResult` object should be used by at most one thread at a time. + It is not safe to call its methods by several threads simultaneously. It is + responsibility of the user to ensure this using a synchronization mechanism + such as mutexes. + + @ingroup devapi_res +*/ + +class SqlResult + : public RowResult +{ +public: + + SqlResult() = default; + + /** + Tell if the current result contains row data. + + If this is the case, rows can be accessed using `RowResult` interface. + Otherwise calling `RowResult` methods throws an error. + */ + + bool hasData() const + { + try { + return Result_detail::has_data(); + } + CATCH_AND_WRAP + } + + + /** + Move to the next result, if there is one. + + Returns true if the next result is available, false if there are no more + results in the reply. Calling `nextResult()` discards the current result. + If it has any rows that has not yet been fetched, these rows are also + discarded. + */ + + bool nextResult() + { + try { + return Row_result_detail::next_result(); + } + CATCH_AND_WRAP + } + + + /** + Get the auto-increment value if one was generated by a table insert + statement. + */ + + uint64_t getAutoIncrementValue() + { + try { + return Result_detail::get_auto_increment(); + } + CATCH_AND_WRAP + } + +private: + + SqlResult(common::Result_init &init) + : RowResult(init) + {} + + template + friend class Executable; +}; + + +// Document based results +// ---------------------- + + +/** + %Result of an operation that returns documents. + + A `DocResult` object gives sequential access to the documents contained in + the result. It is possible to get the documents one-by-one, or fetch and store + all of them at once. One can iterate over the documents using range loop: + `for (DbDoc d : result) ...`. + + @note A `DocResult` object should be used by at most one thread at a time. + It is not safe to call its methods by several threads simultaneously. It is + responsibility of the user to ensure this using a synchronization mechanism + such as mutexes. + + @ingroup devapi_res +*/ + +class DocResult + : public internal::Result_common +{ + +public: + + DocResult() = default; + + /** + Return the current document and move to the next one in the sequence. + + If there are no more documents in this result, returns a null document. + */ + + DbDoc fetchOne() + { + try { + return Doc_result_detail::get_doc(); + } + CATCH_AND_WRAP + } + + /** + Return all remaining documents. + + %Result of this method can be stored in a container such as + `std::list`. Documents that have already been fetched using + `fetchOne()` are not included in the result of `fetchAll()`. + */ + + DocList fetchAll() + { + try { + return Doc_result_detail::get_docs(); + } + CATCH_AND_WRAP + } + + /** + Returns the number of documents contained in the result. + + The method counts only the documents that were not yet fetched and are still + available in the result. + */ + + uint64_t count() + { + try { + return Doc_result_detail::count(); + } + CATCH_AND_WRAP + } + + /* + Iterate over documents (range-for support). + + Documents that have been fetched using iterator are not available when + calling fetchOne() or fetchAll() + */ + + using iterator = Doc_result_detail::iterator; + + iterator begin() + { + try { + return Doc_result_detail::begin(); + } + CATCH_AND_WRAP + } + + iterator end() const + { + try { + return Doc_result_detail::end(); + } + CATCH_AND_WRAP + } + + +private: + + DocResult(common::Result_init &init) + : Result_common(init) + {} + + friend DbDoc; + template + friend class Executable; +}; + +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/row.h b/Libraries/mysql-connector/include/mysqlx/devapi/row.h new file mode 100644 index 0000000..a0dd8a5 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/row.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_ROW_H +#define MYSQLX_ROW_H + +/** + @file + TODO +*/ + + +#include "common.h" +#include "document.h" +#include "detail/row.h" + +#include + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + + +/** + Represents a single row from a result that contains rows. + + Such a row consists of a number of fields, each storing single + value. The number of fields and types of values stored in each + field are described by `RowResult` instance that produced this + row. + + Values of fields can be accessed with `get()` method or using + `row[pos]` expression. Fields are identified by 0-based position. + It is also possible to get raw bytes representing value of a + given field with `getBytes()` method. + + @sa `Value` class. + @todo Support for iterating over row fields with range-for loop. + + @ingroup devapi_res +*/ + +class Row + : private internal::Row_detail +{ + + Row(internal::Row_detail &&other) + try + : Row_detail(std::move(other)) + {} + CATCH_AND_WRAP + + +public: + + Row() {} + + template + explicit Row(T val, Types... vals) + { + try { + Row_detail::set_values(0, val, vals...); + } + CATCH_AND_WRAP + } + + + col_count_t colCount() const + { + try { + return Row_detail::col_count(); + } + CATCH_AND_WRAP + } + + + /** + Get raw bytes representing value of row field at position `pos`. + + The raw bytes are as received from the server. In genral the value + is represented using x-protocol encoding that corresponds to the + type and other meta-data of the given column. This meta-data can + be accessed via `Column` object returned by `RowResult#getColumn()` + method. + + The x-protocol represenation of different value types is documented + [here] + (https://dev.mysql.com/doc/dev/mysql-server/latest/structMysqlx_1_1Resultset_1_1ColumnMetaData.html). + Most types reported by `Column#getType()` method correspond to an x-protocol + value type of the same name. + + All integer types use the x-protocol UINT or SINT encoding, which is + the protobuf variant encoding together with zig-zag encoding for the + signed case + (see ) + + STRING values are encoded using the character set encoding as reported + by `Column#getCharacterSet()` method of the corresponding `Column` object + (usually `utf8mb4`). + + JSON data is represented as a JSON string. ENUM values are represented + as strings with enum constant names. Values of type DATE and TIMESTAMP + use the same representation as DATETIME, with time part empty in case + of DATE values. GEOMETRY values use the internal geometry storage + format described + [here] + (https://dev.mysql.com/doc/refman/8.0/en/gis-data-formats.html). + + Note that raw representation of BYTES and STRING values has an extra + 0x00 byte added at the end, which is not part of the originial data. + It is used to distinguish null values from empty byte sequences. + + @returns null bytes range if given field is NULL. + @throws out_of_range if given row was not fetched from server. + */ + + bytes getBytes(col_count_t pos) const + { + try { + return Row_detail::get_bytes(pos); + } + CATCH_AND_WRAP + } + + + /** + Get reference to row field at position `pos`. + + @throws out_of_range if given field does not exist in the row. + */ + + Value& get(col_count_t pos) + { + try { + return Row_detail::get_val(pos); + } + CATCH_AND_WRAP + } + + + /** + Set value of row field at position `pos`. + + Creates new field if it does not exist. + + @returns Reference to the field that was set. + */ + + Value& set(col_count_t pos, const Value &val) + { + try { + Row_detail::set_values(pos, val); + return Row_detail::get_val(pos); + } + CATCH_AND_WRAP + } + + /** + Get const reference to row field at position `pos`. + + This is const version of method `get()`. + + @throws out_of_range if given field does not exist in the row. + */ + + const Value& operator[](col_count_t pos) const + { + return const_cast(this)->get(pos); + } + + + /** + Get modifiable reference to row field at position `pos`. + + The field is created if it does not exist. In this case + the initial value of the field is NULL. + */ + + Value& operator[](col_count_t pos) + { + ensure_impl(); + try { + return get(pos); + } + catch (const out_of_range&) + { + return set(pos, Value()); + } + } + + /// Check if this row contains fields or is null. + bool isNull() const { return NULL == m_impl; } + operator bool() const { return !isNull(); } + + void clear() + { + try { + Row_detail::clear(); + } + CATCH_AND_WRAP + } + +private: + + using internal::Row_detail::m_impl; + + /// @cond IGNORED + friend internal::Row_result_detail; + friend internal::Table_insert_detail; + /// @endcond +}; + + +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/settings.h b/Libraries/mysql-connector/include/mysqlx/devapi/settings.h new file mode 100644 index 0000000..ced32a8 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/settings.h @@ -0,0 +1,1101 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_DEVAPI_SETTINGS_H +#define MYSQLX_DEVAPI_SETTINGS_H + +/** + @file + TODO +*/ + +#include "common.h" +#include "detail/settings.h" + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + + +/* + TODO: Cross-references to session options inside Doxygen docs do not work. +*/ + +/** + Session creation options + + @note `PRIORITY` should be defined after a `HOST` (`PORT`) to which + it applies. + + @note Specifying `SSL_CA` option requires `SSL_MODE` value of `VERIFY_CA` + or `VERIFY_IDENTITY`. If `SSL_MODE` is not explicitly given then + setting `SSL_CA` implies `VERIFY_CA`. +*/ + +class SessionOption +{ +#define SESS_OPT_ENUM_any(X,N) X = N, +#define SESS_OPT_ENUM_bool(X,N) X = N, +#define SESS_OPT_ENUM_num(X,N) X = N, +#define SESS_OPT_ENUM_str(X,N) X = N, +#define SESS_OPT_ENUM_bool(X,N) X = N, + +public: + + /// Possible session creation options. + + enum Enum { + SESSION_OPTION_LIST(SESS_OPT_ENUM) + LAST + }; + + SessionOption(Enum opt) + : m_opt(opt) + {} + + SessionOption() + {} + + bool operator==(const SessionOption &other) const + { + return m_opt == other.m_opt; + } + + bool operator==(Enum opt) const + { + return m_opt == opt; + } + + bool operator!=(Enum opt) const + { + return m_opt != opt; + } + + operator int() + { + return m_opt; + } + +protected: + int m_opt = LAST; +}; + + +/** + Client creation options +*/ + +class ClientOption + : protected SessionOption +{ + +#define CLIENT_OPT_ENUM_any(X,N) X = -N, +#define CLIENT_OPT_ENUM_bool(X,N) X = -N, +#define CLIENT_OPT_ENUM_num(X,N) X = -N, +#define CLIENT_OPT_ENUM_str(X,N) X = -N, + + +public: + + using SessionEnum = SessionOption::Enum; + + /// Possible client creation options. + + enum Enum { + CLIENT_OPTION_LIST(CLIENT_OPT_ENUM) + }; + + ClientOption() + {} + + ClientOption(SessionOption opt) + : SessionOption(opt) + {} + + ClientOption(Enum opt) + { + m_opt = opt; + } + + ClientOption(SessionEnum opt) + : SessionOption(opt) + {} + + bool operator==(Enum opt) const + { + return m_opt == opt; + } + + bool operator==(SessionEnum opt) const + { + return SessionOption::operator==(opt); + } + + bool operator!=(Enum opt) const + { + return m_opt != opt; + } + + bool operator!=(SessionEnum opt) const + { + return SessionOption::operator!=(opt); + } + + inline operator int() + { + return SessionOption::operator int(); + } + +}; + + +/// @cond DISABLED +// Note: Doxygen gets confused here and renders docs incorrectly. + +inline +std::string OptionName(ClientOption opt) +{ +#define CLT_OPT_NAME_any(X,N) case ClientOption::X: return #X; +#define CLT_OPT_NAME_bool(X,N) CLT_OPT_NAME_any(X,N) +#define CLT_OPT_NAME_num(X,N) CLT_OPT_NAME_any(X,N) +#define CLT_OPT_NAME_str(X,N) CLT_OPT_NAME_any(X,N) + +#define SESS_OPT_NAME_any(X,N) case SessionOption::X: return #X; +#define SESS_OPT_NAME_bool(X,N) SESS_OPT_NAME_any(X,N) +#define SESS_OPT_NAME_num(X,N) SESS_OPT_NAME_any(X,N) +#define SESS_OPT_NAME_str(X,N) SESS_OPT_NAME_any(X,N) +#define SESS_OPT_NAME_bool(X,N) SESS_OPT_NAME_any(X,N) + + + switch (opt) + { + CLIENT_OPTION_LIST(CLT_OPT_NAME) + SESSION_OPTION_LIST(SESS_OPT_NAME) + + default: + throw_error("Unexpected Option"); return ""; + }; +} + +/// @endcond + + +inline std::string ClientOptionName(ClientOption opt) +{ + return OptionName(opt); +} + +inline std::string SessionOptionName(SessionOption opt) +{ + return OptionName(opt); +} + + +/** + Modes to be used with `SSL_MODE` option + \anchor SSLMode +*/ + +enum_class SSLMode +{ +#define SSL_ENUM(X,N) X = N, + + SSL_MODE_LIST(SSL_ENUM) +}; + + +/// @cond DISABLED + +inline +std::string SSLModeName(SSLMode m) +{ +#define MODE_NAME(X,N) case SSLMode::X: return #X; + + switch (m) + { + SSL_MODE_LIST(MODE_NAME) + default: + { + std::ostringstream buf; + buf << "" << std::ends; + return buf.str(); + } + }; +} + +/// @endcond + + +/** + Authentication methods to be used with `AUTH` option. + \anchor AuthMethod +*/ + +enum_class AuthMethod +{ +#define AUTH_ENUM(X,N) X=N, + + AUTH_METHOD_LIST(AUTH_ENUM) +}; + + +/// @cond DISABLED + +inline +std::string AuthMethodName(AuthMethod m) +{ +#define AUTH_NAME(X,N) case AuthMethod::X: return #X; + + switch (m) + { + AUTH_METHOD_LIST(AUTH_NAME) + default: + { + std::ostringstream buf; + buf << "" << std::ends; + return buf.str(); + } + }; +} + +/// @endcond + +/** + Values to be used with `COMPRESSION` option + \anchor CompressionMode +*/ + +enum_class CompressionMode +{ +#define COMPRESSION_ENUM(X,N) X = N, + + COMPRESSION_MODE_LIST(COMPRESSION_ENUM) +}; + +/// @cond DISABLED + +inline +std::string CompressionModeName(CompressionMode m) +{ +#define COMPRESSION_NAME(X,N) case CompressionMode::X: return #X; + + switch (m) + { + COMPRESSION_MODE_LIST(COMPRESSION_NAME) + default: + { + std::ostringstream buf; + buf << "" << std::ends; + return buf.str(); + } + }; +} + +/// @endcond + + +namespace internal { + + +/* + Encapsulate public enumerations in the Settings_traits class to be used + by Settings_detail<> template. +*/ + +struct Settings_traits +{ + using Options = mysqlx::SessionOption; + using COptions = mysqlx::ClientOption; + using SSLMode = mysqlx::SSLMode; + using AuthMethod = mysqlx::AuthMethod; + using CompressionMode = mysqlx::CompressionMode; + + static std::string get_mode_name(SSLMode mode) + { + return SSLModeName(mode); + } + + static std::string get_option_name(COptions opt) + { + return ClientOptionName(opt); + } + + static std::string get_auth_name(AuthMethod m) + { + return AuthMethodName(m); + } +}; + + +template<> +PUBLIC_API +void +internal::Settings_detail:: +do_set(session_opt_list_t &&opts); + + +template +class iterator +{ + base_iterator m_it; + std::pair m_pair; + +public: + using iterator_category = std::input_iterator_tag; + using value_type = std::pair; + + iterator(const base_iterator &init) : m_it(init) {} + + iterator(const iterator &init) : m_it(init.m_it) {} + + std::pair &operator*() { + auto &el = *m_it; + m_pair.first = static_cast(el.first); + m_pair.second = el.second; + return m_pair; + } + + std::pair* operator->() + { + return &operator*(); + } + + iterator& operator++() + { + ++m_it; + return *this; + } + + iterator& operator--() + { + --m_it; + return *this; + } + + bool operator !=(const iterator &other) + { + return m_it != other.m_it; + } + +}; + + +} // internal namespace + + +class Client; +class Session; + +/** + Represents session options to be passed at session creation time. + + SessionSettings can be constructed using a connection string, common + connect options (host, port, user, password, database) or with a list + of `SessionOption` constants, each followed by the option value. + + Examples: + ~~~~~~ + + SessionSettings from_url("mysqlx://user:pwd@host:port/db?ssl-mode=required"); + + SessionSettings from_options("host", port, "user", "pwd", "db"); + + SessionSettings from_option_list( + SessionOption::USER, "user", + SessionOption::PWD, "pwd", + SessionOption::HOST, "host", + SessionOption::PORT, port, + SessionOption::DB, "db", + SessionOption::SSL_MODE, SSLMode::REQUIRED + ); + ~~~~~~ + + The HOST, PORT and SOCKET settings can be repeated to build a list of hosts + to be used by the connection fail-over logic when creating a session (see + description of `Session` class). In that case each host can be assigned + a priority by setting the `PRIORITY` option. If priorities are not explicitly + assigned, hosts are tried in the order in which they are specified in session + settings. If priorities are used, they must be assigned to all hosts + specified in the settings. + + @ingroup devapi +*/ + +class SessionSettings + : private internal::Settings_detail +{ + using Value = mysqlx::Value; + +public: + + /** + Create session settings from a connection string. + + Connection sting has the form + + "user:pass@connection-data/db?option&option" + + with optional `mysqlx://` prefix. + + The `connetction-data` part is either a single host address or a coma + separated list of hosts in square brackets: `[host1, host2, ..., hostN]`. + In the latter case the connection fail-over logic will be used when + creating the session. + + A single host address is either a DNS host name, an IPv4 address of + the form `nn.nn.nn.nn` or an IPv6 address of the form `[nn:nn:nn:...]`. + On Unix systems a host can be specified as a path to a Unix domain + socket - this path must start with `/` or `.`. + + Characters like `/` in the connection data, which otherwise have a special + meaning inside a connection string, must be represented using percent + encoding (e.g., `%2F` for `/`). Another option is to enclose a host name or + a socket path in round braces. For example, one can write + + "mysqlx://(./path/to/socket)/db" + + instead of + + "mysqlx://.%2Fpath%2Fto%2Fsocket/db" + + To specify priorities for hosts in a multi-host settings, use list of pairs + of the form `(address=host,priority=N)`. If priorities are specified, they + must be given to all hosts in the list. + + The optional `db` part of the connection string defines the default schema + of the session. + + Possible connection options are: + + - `ssl-mode=...` : see `SessionOption::SSL_MODE`; the value is a case + insensitive name of the SSL mode + - `ssl-ca=...` : see `SessionOption::SSL_CA` + - `auth=...`: see `SessionOption::AUTH`; the value is a case insensitive + name of the authentication method + - `connect-timeout=...`: see `SessionOption::CONNECT_TIMEOUT` + - `connection-attributes=[...]` : see `SessionOption::CONNECTION_ATTRIBUTES` + but the key-value pairs are not given by a JSON document but as a list;\n + Examples:\n + `"mysqlx://user@host?connection-attributes=[foo=bar,qux,baz=]"` - + specify additional attributes to be sent\n + `"mysqlx://user@host?connection-attributes=false"` - + send no connection attributes\n + `"mysqlx://user@host?connection-attributes=true"` - + send default connection attributes\n + `"mysqlx://user@host?connection-attributes=[]"` - + the same as setting to `true`\n + `"mysqlx://user@host?connection-attributes"` - + the same as setting to `true`\n + - `tls-versions=[...]` : see `SessionOption::TLS_VERSIONS` + - `tls-ciphersuites=[...]` : see `SessionOption::TLS_CIPHERSUITES` + - `compression=...` : see `SessionOption::COMPRESSION` + - `compression-algorithms=[...]` : see `SessionOption::COMPRESSION_ALGORITHMS` + */ + + SessionSettings(const string &uri) + { + try { + Settings_detail::set_from_uri(uri); + } + CATCH_AND_WRAP + } + + + /** + Explicitly specify basic connection settings. + + @note Session settings constructed this way request an SSL connection + by default. + */ + + SessionSettings( + const std::string &host, unsigned port, + const string &user, + const char *pwd = NULL, + const string &db = string() + ) + { + set( + SessionOption::HOST, host, + SessionOption::PORT, port, + SessionOption::USER, user + ); + + if (pwd) + set(SessionOption::PWD, std::string(pwd)); + + if (!db.empty()) + set(SessionOption::DB, db); + } + + SessionSettings( + const std::string &host, unsigned port, + const string &user, + const std::string &pwd, + const string &db = string() + ) + : SessionSettings(host, port, user, pwd.c_str(), db) + {} + + /** + Basic settings with the default port + + @note Session settings constructed this way request an SSL connection + by default. + */ + + SessionSettings( + const std::string &host, + const string &user, + const char *pwd = NULL, + const string &db = string() + ) + : SessionSettings(host, DEFAULT_MYSQLX_PORT, user, pwd, db) + {} + + SessionSettings( + const std::string &host, + const string &user, + const std::string &pwd, + const string &db = string() + ) + : SessionSettings(host, DEFAULT_MYSQLX_PORT, user, pwd, db) + {} + + /** + Basic settings for a session on the localhost. + + @note Session settings constructed this way request an SSL connection + by default. + */ + + SessionSettings( + unsigned port, + const string &user, + const char *pwd = NULL, + const string &db = string() + ) + : SessionSettings("localhost", port, user, pwd, db) + {} + + SessionSettings( + unsigned port, + const string &user, + const std::string &pwd, + const string &db = string() + ) + : SessionSettings("localhost", port, user, pwd.c_str(), db) + {} + + /* + Templates below are here to take care of the optional password + parameter of type const char* (which can be either 3-rd or 4-th in + the parameter list). Without these templates passing + NULL as password is ambiguous because NULL is defined as 0, + which has type int, and then it could be treated as port value. + */ + + template < + typename HOST, + typename PORT, + typename USER, + typename... T, + typename std::enable_if< + std::is_constructible::value + >::type* = nullptr + > + SessionSettings(HOST h, PORT p, USER u, long, T... args) + : SessionSettings(h, p, u, nullptr, args...) + {} + + + template < + typename PORT, + typename USER, + typename... T, + typename std::enable_if< + std::is_constructible::value + >::type* = nullptr + > + SessionSettings(PORT p, USER u, long, T... args) + : SessionSettings(p, u, nullptr, args...) + {} + + + /** + Specify settings as a list of session options. + + The list of options consist of a SessionOption constant, + identifying the option to set, followed by the value of the option. + + Example: + ~~~~~~ + SessionSettings from_option_list( + SessionOption::USER, "user", + SessionOption::PWD, "pwd", + SessionOption::HOST, "host", + SessionOption::PORT, port, + SessionOption::DB, "db", + SessionOption::SSL_MODE, SessionSettings::SSLMode::REQUIRED + ); + ~~~~~~ + */ + + template + SessionSettings(SessionOption::Enum opt, R&&...rest) + { + try { + // set means that only SessionOption can be used + Settings_detail::set(opt, std::forward(rest)...); + } + CATCH_AND_WRAP + } + + /* + Return an iterator pointing to the first element of the SessionSettings. + */ + using iterator = internal::iterator; + + iterator begin() + { + try { + return Settings_detail::begin(); + } + CATCH_AND_WRAP + } + + /* + Return an iterator pointing to the last element of the SessionSettings. + */ + + iterator end() + { + try { + return Settings_detail::end(); + } + CATCH_AND_WRAP + } + + + /** + Find the specified option @p opt and returns its Value. + + Returns NULL Value if not found. + + @note For option such as `HOST`, which can repeat several times in + the settings, only the last value is reported. + */ + + Value find(SessionOption opt) + { + try { + return Settings_detail::get(opt); + } + CATCH_AND_WRAP + } + + /** + Set session options. + + Accepts a list of one or more `SessionOption` constants, each followed by + the option value. Options specified here are added to the current settings. + + Repeated `HOST`, `PORT`, `SOCKET` and `PRIORITY` options build a list of + hosts to be used by the fail-over logic. For other options, if they are set + again, the new value overrides the previous setting. + + @note + When using `HOST`, `PORT` and `PRIORITY` options to specify a single + host, all have to be specified in the same `set()` call. + */ + + template + void set(SessionOption opt, R&&... rest) + { + try { + // set means that only SessionOption can be used + Settings_detail::set(opt, std::forward(rest)...); + } + CATCH_AND_WRAP + } + + /** + Clear all settings specified so far. + */ + + void clear() + { + try { + Settings_detail::clear(); + } + CATCH_AND_WRAP + } + + /** + Remove all settings for the given option @p opt. + + @note For option such as `HOST`, which can repeat several times in + the settings, all occurrences are erased. + */ + + void erase(SessionOption opt) + { + try { + Settings_detail::erase(static_cast(opt)); + } + CATCH_AND_WRAP + } + + + /** + Check if option @p opt was defined. + */ + + bool has_option(SessionOption opt) + { + try { + return Settings_detail::has_option(opt); + } + CATCH_AND_WRAP + } + +private: + + friend Client; + friend Session; +}; + + +/** + ClientSettings are used to construct Client objects. + + It can be constructed using a connection string plus a JSON with client + options, or by setting each ClientOption and SessionOption with its + correspondant value. + + @ingroup devapi + */ + +class ClientSettings + : private internal::Settings_detail +{ + +public: + + using Base = internal::Settings_detail; + using Value = mysqlx::Value; + + /* + Return an iterator pointing to the first element of the SessionSettings. + */ + + using iterator = internal::iterator; + + iterator begin() + { + try { + return Settings_detail::begin(); + } + CATCH_AND_WRAP + } + + /* + Return an iterator pointing to the last element of the SessionSettings. + */ + + iterator end() + { + try { + return Settings_detail::end(); + } + CATCH_AND_WRAP + } + + /** + Create client settings from a connection string. + + @see SessionSettings + */ + + ClientSettings(const string &uri) + { + try { + Settings_detail::set_from_uri(uri); + } + CATCH_AND_WRAP + } + + /** + Create client settings from a connection string and a ClientSettings object + + @see SessionSettings + */ + + ClientSettings(const string &uri, ClientSettings &opts) + { + try { + Settings_detail::set_from_uri(uri); + Settings_detail::set_client_opts(opts); + } + CATCH_AND_WRAP + } + + /** + Create client settings from a connection string and. Client options are + expressed in JSON format. Here is an example: + ~~~~~~ + { "pooling": { + "enabled": true, + "maxSize": 25, + "queueTimeout": 1000, + "maxIdleTime": 5000} + } + ~~~~~~ + + All options are defined under a document with key vale "pooling". Inside the + document, the available options are these: + - `enabled` : boolean value that enable or disable connection pooling. If + disabled, session created from pool are the same as created + directly without client handle. + Enabled by default. + - `maxSize` : integer that defines the max pooling sessions possible. If + uses tries to get session from pool when maximum sessions are + used, it will wait for an available session untill + `queueTimeout`. + Defaults to 25. + - `queueTimeout` : integer value that defines the time, in milliseconds, + that client will wait to get an available session. + By default it doesn't timeouts. + - `maxIdleTime` : integer value that defines the time, in milliseconds, that + an available session will wait in the pool before it is + removed. + By default it doesn't cleans sessions. + + */ + + ClientSettings(const string &uri, const DbDoc &options) + { + try { + Settings_detail::set_from_uri(uri); + std::stringstream str_opts; + str_opts << options; + Settings_detail::set_client_opts(str_opts.str()); + } + CATCH_AND_WRAP + } + + /** + Create client settings from a connection string and. Client options are + expressed in JSON format. Here is an example: + ~~~~~~ + { "pooling": { + "enabled": true, + "maxSize": 25, + "queueTimeout": 1000, + "maxIdleTime": 5000} + } + ~~~~~~ + + All options are defined under a document with key vale "pooling". Inside the + document, the available options are these: + - `enabled` : boolean value that enable or disable connection pooling. If + disabled, session created from pool are the same as created + directly without client handle. + Enabled by default. + - `maxSize` : integer that defines the max pooling sessions possible. If + uses tries to get session from pool when maximum sessions are + used, it will wait for an available session untill + `queueTimeout`. + Defaults to 25. + - `queueTimeout` : integer value that defines the time, in milliseconds, + that client will wait to get an available session. + By default it doesn't timeouts. + - `maxIdleTime` : integer value that defines the time, in milliseconds, that + an available session will wait in the pool before it is + removed. + By default it doesn't cleans sessions. + + */ + + ClientSettings(const string &uri, const char *options) + { + try { + Settings_detail::set_from_uri(uri); + Settings_detail::set_client_opts(options); + } + CATCH_AND_WRAP + } + + /** + Create client settings from a connection string and client settings as a + list of client options. + + The list of options consist of a ClientOption constant, + identifying the option to set, followed by the value of the option. + + Example: + ~~~~~~ + ClientSettings from_option_list( "mysqlx://root@localhost", + ClientOption::POOLING, true, + ClientOption::POOL_MAX_SIZE, max_connections, + ClientOption::POOL_QUEUE_TIMEOUT, std::chrono::seconds(100), + ClientOption::POOL_MAX_IDLE_TIME, std::chrono::microseconds(1) + ); + ~~~~~~ + + ClientOption::POOL_QUEUE_TIMEOUT and ClientOption::POOL_MAX_IDLE_TIME can + be specified using std::chrono::duration objects, or by integer values, with + the latest to be specified in milliseconds. + + @see SessionSettings + */ + + template + ClientSettings(const string &uri, mysqlx::ClientOption opt, R... rest) + try + : ClientSettings(uri) + { + // set means that both SessionOption and ClientOption can be used + Settings_detail::set(opt, std::forward(rest)...); + } + CATCH_AND_WRAP + + + template + ClientSettings(mysqlx::ClientOption opt, R&&...rest) + { + try { + // set means that both SessionOption and ClientOption can be used + Settings_detail::set(opt, std::forward(rest)...); + } + CATCH_AND_WRAP + } + + /** + Find the specified option @p opt and returns its Value. + + Returns NULL Value if not found. + + */ + + Value find(mysqlx::ClientOption opt) + { + try { + return Settings_detail::get(opt); + } + CATCH_AND_WRAP + } + + /** + Set client and session options. + + Accepts a list of one or more `ClientOption` or `SessionOption` constants, + each followed by the option value. Options specified here are added to the + current settings. + + Repeated `HOST`, `PORT`, `SOCKET` and `PRIORITY` options build a list of + hosts to be used by the fail-over logic. For other options, if they are set + again, the new value overrides the previous setting. + + @note + When using `HOST`, `PORT` and `PRIORITY` options to specify a single + host, all have to be specified in the same `set()` call. + */ + + template + void set(OPT opt, R&&... rest) + { + try { + // set means that both SessionOption and ClientOption can be used + Settings_detail::set(opt, std::forward(rest)...); + } + CATCH_AND_WRAP + } + + + /** + Clear all settings specified so far. + */ + + void clear() + { + try { + Settings_detail::clear(); + } + CATCH_AND_WRAP + } + + /** + Remove the given option @p opt. + */ + + void erase(mysqlx::ClientOption opt) + { + try { + Settings_detail::erase(static_cast(opt)); + } + CATCH_AND_WRAP + } + + + /** + Check if option @p opt was defined. + */ + + bool has_option(ClientOption::Enum opt) + { + try { + return Settings_detail::has_option(opt); + } + CATCH_AND_WRAP + } + + /** + Check if option @p opt was defined. + */ + + bool has_option(SessionOption::Enum opt) + { + try { + return Settings_detail::has_option(opt); + } + CATCH_AND_WRAP + } + +private: + friend Client; + friend Session; +}; + + +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/devapi/table_crud.h b/Libraries/mysql-connector/include/mysqlx/devapi/table_crud.h new file mode 100644 index 0000000..f03ad89 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/devapi/table_crud.h @@ -0,0 +1,516 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_TABLE_CRUD_H +#define MYSQLX_TABLE_CRUD_H + +/** + @file + Crud operations on tables. + + Classes declared here represent CRUD operations on a table. They are + analogous to collection CRUD operation classes defined in collection_crud.h. + + The following classes for table CRUD operations are defined: + - TableInsert + - TableRemove + - TableSelect + - TableUpdate + + CRUD operation objects can be created directly, or assigned from + result of DevAPI methods that create such operations: + ~~~~~~ + TableInsert insert_op(table); + TableSelect select_op = table.select(...).orderBy(...); + ~~~~~~ + + CRUD operation objects have methods which can modify the operation + before it gets executed. For example `TableInsert::values()` + appends a row to the list of rows that should be inserted into a table + by the given TableInsert operation. These methods can be chained + as allowed by the fluent API grammar. +*/ + + +#include "common.h" +#include "result.h" +#include "executable.h" +#include "crud.h" + + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +class Table; + +// --------------------------------------------------------------------------- + +class TableInsert; + +namespace internal { + + struct Table_insert_base + : public Executable + {}; + +} + +/** + An operation which inserts rows into a table. + + This class defines methods that specify the rows to be inserted into + the table. + + @todo Check that every row passed to .values() call has + the same number of values. The column count should match + the one in insert(c1,...) call. For insert() without column + list, it should match the number of columns in the table. + + @ingroup devapi_op +*/ + +class TableInsert + : public internal::Table_insert_base + , internal::Table_insert_detail +{ + +protected: + + template + TableInsert(Table &table, const Cols&... cols) + : TableInsert(table) + { + add_columns(get_impl(), cols...); + } + +public: + + // Create operation which inserts rows into given table. + + TableInsert(Table &table) + { + try { + reset(internal::Crud_factory::mk_insert(table)); + } + CATCH_AND_WRAP + } + + TableInsert(const internal::Table_insert_base &other) + { + internal::Table_insert_base::operator=(other); + } + + TableInsert(internal::Table_insert_base &&other) + { + internal::Table_insert_base::operator=(std::move(other)); + } + + using internal::Table_insert_base::operator=; + + /// Add the given row to the list of rows to be inserted. + + virtual TableInsert& values(const Row &row) + { + try { + add_rows(get_impl(), row); + return *this; + } + CATCH_AND_WRAP + } + + /** + Add a single row consisting of the specified values to the list of + rows to be inserted. + */ + + template + TableInsert& values(Types... rest) + { + try { + add_values(get_impl(), rest...); + return *this; + } + CATCH_AND_WRAP + } + + /** + Add rows from a container such as vector or list. + */ + + template + TableInsert& rows(const Container &cont) + { + try { + add_rows(get_impl(), cont); + return *this; + } + CATCH_AND_WRAP + } + + /** + Add rows from a range given by two iterators. + */ + + template + TableInsert& rows(const It &begin, const It &end) + { + try { + add_rows(get_impl(), begin, end); + return *this; + } + CATCH_AND_WRAP + } + + /** + Add the given list of rows. + */ + + template + TableInsert& rows(const Row &first, Types... rest) + { + try { + add_rows(get_impl(), first, rest...); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Table_insert_detail::Impl; + + Impl* get_impl() + { + return static_cast(internal::Table_insert_base::get_impl()); + } + + ///@cond IGNORED + friend Table; + ///@endcond +}; + + +// --------------------------------------------------------------------------- + +class TableSelect; + +namespace internal { + + class Op_view_create_alter; + + struct Table_select_cmd + : public Executable + {}; + + struct Table_select_base + : public Group_by < Having < Order_by < Limit < Offset< Bind_parameters< + Set_lock< Table_select_cmd, common::Table_select_if > + > > > > > > + {}; + +} + + +/** + An operation which selects rows from a table. + + The class defines various methods, such as `where()`, to specify which rows + should be returned and in which order. + + For each row the operation can return all fields from the + row or a set of values defined by projection expressions + specified when the operation was created. + + @ingroup devapi_op +*/ + +class TableSelect + : public internal::Table_select_base + , internal::Table_select_detail +{ + + using Operation = Table_select_base; + +public: + + TableSelect(Table &table) + { + try { + reset(internal::Crud_factory::mk_select(table)); + } + CATCH_AND_WRAP + } + + template + TableSelect(Table &table, const PROJ&... proj) + : TableSelect(table) + { + try { + add_proj(get_impl(), proj...); + } + CATCH_AND_WRAP + } + + TableSelect(const internal::Table_select_cmd &other) + { + internal::Table_select_cmd::operator=(other); + } + + TableSelect(internal::Table_select_cmd &&other) + { + internal::Table_select_cmd::operator=(std::move(other)); + } + + using internal::Table_select_cmd::operator=; + + /** + Specify row selection criteria. + + The criteria is specified as a Boolean expression string. + */ + + Operation& where(const string& expr) + { + try { + get_impl()->set_where(expr); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Table_select_if; + + Impl* get_impl() + { + return static_cast(internal::Table_select_base::get_impl()); + } + + ///@cond IGNORED + friend Table; + friend internal::Op_view_create_alter; + ///@endcond +}; + + +// --------------------------------------------------------------------------- + +class TableUpdate; + +namespace internal { + + struct Table_update_cmd + : public Executable + {}; + + struct Table_update_base + : public Order_by< Limit< Bind_parameters< Table_update_cmd > > > + {}; + +} + + +/** + An operation which updates rows stored in a table. + + Methods of this clas specify modifications to be applied to each row as well + as the set of rows that should be modified. + + @ingroup devapi_op +*/ + +class TableUpdate + : public internal::Table_update_base +{ + using Operation = internal::Table_update_base; + + TableUpdate(Table& table) + { + try { + reset(internal::Crud_factory::mk_update(table)); + } + CATCH_AND_WRAP + } + +public: + + TableUpdate(Table &table, const string &expr) + : TableUpdate(table) + { + where(expr); + } + + TableUpdate(const internal::Table_update_cmd &other) + { + internal::Table_update_cmd::operator=(other); + } + + TableUpdate(internal::Table_update_cmd &&other) + { + internal::Table_update_cmd::operator=(std::move(other)); + } + + using internal::Table_update_cmd::operator=; + + /** + Set the given field in a row to the given value. + + The value can be either a direct literal or an expression given + as `expr()`, to be evaluated in the server. + */ + + TableUpdate& set(const string& field, const Value &val) + { + try { + get_impl()->add_set(field, (const common::Value&)val); + return *this; + } + CATCH_AND_WRAP + } + + /** + Specify selection criteria for rows that should be updated. + */ + + Operation& where(const string& expr) + { + try { + get_impl()->set_where(expr); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Table_update_if; + + Impl* get_impl() + { + return static_cast(internal::Table_update_base::get_impl()); + } + + ///@cond IGNORED + friend Table; + ///@endcond +}; + + +// --------------------------------------------------------------------------- + +class TableRemove; + +namespace internal { + + struct Table_remove_cmd + : public Executable + {}; + + struct Table_remove_base + : Order_by< Limit< Bind_parameters< Table_remove_cmd > > > + {}; + +} + + +/** + An operation which removes rows from a table. + + The class defines methods to specify which rows should be removed. + + @ingroup devapi_op +*/ + +class TableRemove + : public internal::Table_remove_base +{ + using Operation = internal::Table_remove_base; + + TableRemove(Table& table) + { + try { + reset(internal::Crud_factory::mk_remove(table)); + } + CATCH_AND_WRAP + } + +public: + + TableRemove(Table &table, const string &expr) + : TableRemove(table) + { + where(expr); + } + + TableRemove(const internal::Table_remove_cmd &other) + { + internal::Table_remove_cmd::operator=(other); + } + + TableRemove(internal::Table_remove_cmd &&other) + { + internal::Table_remove_cmd::operator=(std::move(other)); + } + + using internal::Table_remove_cmd::operator=; + + /** + Specify selection criteria for rows to be removed. + */ + + Operation& where(const string &expr) + { + try { + get_impl()->set_where(expr); + return *this; + } + CATCH_AND_WRAP + } + +protected: + + using Impl = common::Table_remove_if; + + Impl* get_impl() + { + return static_cast(internal::Table_remove_base::get_impl()); + } + + ///@cond IGNORED + friend Table; + ///@endcond +}; + + +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/version_info.h b/Libraries/mysql-connector/include/mysqlx/version_info.h new file mode 100644 index 0000000..c69cbd3 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/version_info.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQLX_COMMON_VERSION_INFO +#define MYSQLX_COMMON_VERSION_INFO + +/* + Version information which is used for example for default + connection attributes. + + When build system is configured by cmake, a new file is generated + from this one with version and license values substituted by + cmake and build system is configured so that the generated + header takes precedence over this one. But code can be built even + if header with real values was not generated - in that case the + values specified here will be used. +*/ + +#define MYSQL_CONCPP_NAME "mysql-connector-cpp" +#define MYSQL_CONCPP_VERSION "9.0.0" +#define MYSQL_CONCPP_LICENSE "GPL-2.0" + +#define MYSQL_CONCPP_VERSION_MAJOR 9 +#define MYSQL_CONCPP_VERSION_MINOR 0 +#define MYSQL_CONCPP_VERSION_MICRO 0 + +#define MYSQL_CONCPP_VERSION_NUMBER 9000000 + +#endif diff --git a/Libraries/mysql-connector/include/mysqlx/xapi.h b/Libraries/mysql-connector/include/mysqlx/xapi.h new file mode 100644 index 0000000..7740de2 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/xapi.h @@ -0,0 +1,3553 @@ +/* + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + @defgroup xapi X DevAPI for C + + Functions and types defined by X DevAPI for C. See @ref xapi_example for introduction. + + @{ + @defgroup xapi_sess Session operations + + @defgroup xapi_coll Statements operating on document collections + + @defgroup xapi_tbl Statements operating on tables + + @defgroup xapi_sql SQL execution + + @defgroup xapi_ddl DDL statements + + @note To create a table or a view, use reqular SQL statement. + + @defgroup xapi_stmt Statement execution + + @defgroup xapi_res Result processing + + @defgroup xapi_md Meta data access + + @defgroup xapi_diag Diagnostics + @} +*/ + + +/** + @file + The main header for MySQL Connector/C++ X DevAPI for C. + + This header should be included by C and C++ code which uses the X DevAPI + for C implemented by MySQL Connector/C++ + + @ingroup xapi +*/ + + +#ifndef MYSQL_XAPI_H +#define MYSQL_XAPI_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "common_constants.h" +#include "common/api.h" + +#include +#include +#include + +/** + @addtogroup xapi + @{ +*/ + + +// FIXME +#define STDCALL + +///////////////////// COMMON TYPE DECLARATIONS, REMOVE LATER + +typedef char object_id[16]; +typedef object_id* MYSQLX_GUID; + +/** Return value indicating function/operation success. */ + +#define RESULT_OK 0 + +/** + Return value flag indicating that the last reading operation + did not finish reading to the end and there is still more data + to be fetched by functions such as mysqlx_get_bytes() +*/ + +#define RESULT_MORE_DATA 8 + +/** + Return value flag indicating end of data items (documents or + rows) in a query result. This is used by functions which iterate + over result data. +*/ + +#define RESULT_NULL 16 + +/** + Return value flag indicating that operation generated + information diagnostic entries. +*/ + +#define RESULT_INFO 32 + +/** Return value flag indicating that operation generated warnings. */ + +#define RESULT_WARNING 64 + +/** Return value flag indicating function/operation error. */ + +#define RESULT_ERROR 128 + + +#define MYSQLX_MAX_ERROR_LEN 255 +#define MYSQLX_NULL_TERMINATED 0xFFFFFFFF + +#define MYSQLX_ERR_UNKNOWN 0xFFFF + +#define MYSQLX_COLLATION_UNDEFINED 0 + + +/* + Error codes +*/ + +#define MYSQLX_ERROR_INDEX_OUT_OF_RANGE 1 + +/* + Error messages +*/ + +#define MYSQLX_ERROR_INDEX_OUT_OF_RANGE_MSG "Index is out of range" +#define MYSQLX_ERROR_MISSING_SCHEMA_NAME_MSG "Missing schema name" +#define MYSQLX_ERROR_MISSING_TABLE_NAME_MSG "Missing table name" +#define MYSQLX_ERROR_MISSING_VIEW_NAME_MSG "Missing view name" +#define MYSQLX_ERROR_MISSING_COLLECTION_NAME_MSG "Missing collection name" +#define MYSQLX_ERROR_MISSING_COLLECTION_OPT_MSG "Missing collection options" +#define MYSQLX_ERROR_MISSING_VIEW_NAME_MSG "Missing view name" +#define MYSQLX_ERROR_MISSING_KEY_NAME_MSG "Missing key name" +#define MYSQLX_ERROR_MISSING_HOST_NAME "Missing host name" +#define MYSQLX_ERROR_MISSING_SOCKET_NAME "Missing socket name" +#define MYSQLX_ERROR_MISSING_CONN_INFO "Missing connecting information" +#define MYSQLX_ERROR_HANDLE_NULL_MSG "Handle cannot be NULL" +#define MYSQLX_ERROR_VIEW_INVALID_STMT_TYPE "Invalid statement type for View. Only SELECT type is supported" +#define MYSQLX_ERROR_VIEW_TYPE_MSG "Statement must be of VIEW type" +#define MYSQLX_ERROR_OUTPUT_BUFFER_NULL "The output buffer cannot be NULL" +#define MYSQLX_ERROR_OUTPUT_BUFFER_ZERO "The output buffer cannot have zero length" +#define MYSQLX_ERROR_OUTPUT_VARIABLE_NULL "The output variable cannot be NULL" +#define MYSQLX_ERROR_OP_NOT_SUPPORTED "The operation is not supported by the function" +#define MYSQLX_ERROR_WRONG_SSL_MODE "Wrong value for SSL Mode" +#define MYSQLX_ERROR_NO_TLS_SUPPORT "Can not create TLS session - this connector is built without TLS support" +#define MYSQLX_ERROR_MIX_PRIORITY "Mixing hosts with and without priority is not allowed" +#define MYSQLX_ERROR_DUPLICATED_OPTION "Option already defined" +#define MYSQLX_ERROR_MAX_PRIORITY "Priority should be a value between 0 and 100" +#define MYSQLX_ERROR_AUTH_METHOD "Unknown authentication method" +#define MYSQLX_ERROR_ROW_LOCKING "Row locking is supported only for SELECT and FIND" +#define MYSQLX_ERROR_WRONG_LOCKING_MODE "Wrong value for the row locking mode" +#define MYSQLX_ERROR_WRONG_EXPRESSION "Expression could not be parsed" +#define MYSQLX_ERROR_EMPTY_JSON "Empty JSON document string" + + +/* Opaque structures*/ + +/** + Type of error handles. + + Error handles give access to diagnostic information from the session + and statement operations. + + @see mysqlx_error() +*/ + +typedef struct mysqlx_error_struct mysqlx_error_t; + + +/** + Type of session handles. + + @see mysqlx_get_session() +*/ + +typedef struct mysqlx_session_struct mysqlx_session_t; + +/** + Type of client handles. + + @see mysqlx_get_client() +*/ + +typedef struct mysqlx_client_struct mysqlx_client_t; + + +/** + Type of handles for session configuration data. + + Session can be created using previously prepared session configuration + data. New configuration data is allocated by `mysqlx_session_options_new()` + and can be manipulated using related functions. + + @see mysqlx_get_session_from_options(), mysqlx_session_options_new(), + mysqlx_session_option_set(), mysqlx_free(). +*/ + +typedef struct mysqlx_session_options_struct mysqlx_session_options_t; + +/** + Type of handles for collection create/modify options. + + @see mysqlx_collection_options_new(), mysqlx_collection_options_set(), + mysqlx_free(). +*/ + +typedef struct mysqlx_collection_options_struct mysqlx_collection_options_t; + +/** + Type of database schema handles. + + @see mysqlx_get_schema() +*/ + +typedef struct mysqlx_schema_struct mysqlx_schema_t; + + +/** + Type of collection handles. + + @see mysqlx_get_collection() +*/ + +typedef struct mysqlx_collection_struct mysqlx_collection_t; + + +/** + Type of table handles. + + @see mysqlx_get_table() +*/ +typedef struct mysqlx_table_struct mysqlx_table_t; + + +/** + Type of statement handles. + + Some X DevAPI for C functions create statements without executing them. These + functions return a statement handle which can be used to define statement + properties and then execute it. + + @see mysqlx_sql_new(), mysqlx_table_select_new(), mysqlx_table_insert_new(), + mysqlx_table_update_new(), mysqlx_table_delete_new(), + mysqlx_collection_find_new(), mysqlx_collection_modify_new(), + mysqlx_collection_add_new(), mysqlx_collection_remove_new() +*/ + +typedef struct mysqlx_stmt_struct mysqlx_stmt_t; + +typedef struct Mysqlx_diag_base mysqlx_object_t; + + +/** + Type of row handles. + + @see mysqlx_row_fetch_one() +*/ + +typedef struct mysqlx_row_struct mysqlx_row_t; + + +/** + Type of result handles. + + Functions which produce results return a result handle which is + then used to examine the result. + + @see mysqlx_execute(), mysqlx_store_result(), mysqlx_row_fetch_one(), + mysqlx_json_fetch_one(), mysqlx_next_result()) +*/ + +typedef struct mysqlx_result_struct mysqlx_result_t; + + +/** + The data type identifiers used in MYSQLX API. +*/ + +typedef enum mysqlx_data_type_enum +{ + MYSQLX_TYPE_UNDEFINED = 0, + + /* Column types as defined in protobuf (mysqlx_resultset.proto)*/ + MYSQLX_TYPE_SINT = 1, /**< 64-bit signed integer number type*/ + MYSQLX_TYPE_UINT = 2, /**< 64-bit unsigned integer number type*/ + MYSQLX_TYPE_DOUBLE = 5, /**< Floating point double number type*/ + MYSQLX_TYPE_FLOAT = 6, /**< Floating point float number type*/ + MYSQLX_TYPE_BYTES = 7, /**< Bytes array type*/ + MYSQLX_TYPE_TIME = 10, /**< Time type*/ + MYSQLX_TYPE_DATETIME = 12,/**< Datetime type*/ + MYSQLX_TYPE_SET = 15, /**< Set type*/ + MYSQLX_TYPE_ENUM = 16,/**< Enum type*/ + MYSQLX_TYPE_BIT = 17, /**< Bit type*/ + MYSQLX_TYPE_DECIMAL = 18,/**< Decimal type*/ + + /* Column types from DevAPI (no number constants assigned, just names)*/ + MYSQLX_TYPE_BOOL = 19,/**< Bool type*/ + MYSQLX_TYPE_JSON = 20,/**< JSON type*/ + MYSQLX_TYPE_STRING = 21,/**< String type*/ + MYSQLX_TYPE_GEOMETRY = 22,/**< Geometry type*/ + MYSQLX_TYPE_TIMESTAMP= 23,/**< Timestamp type*/ + + MYSQLX_TYPE_NULL = 100, /**< NULL value*/ + MYSQLX_TYPE_EXPR = 101 /**< Expression type*/ +} mysqlx_data_type_t; + +#define PARAM_SINT(A) (void*)MYSQLX_TYPE_SINT, (int64_t)A +#define PARAM_UINT(A) (void*)MYSQLX_TYPE_UINT, (uint64_t)A +#define PARAM_FLOAT(A) (void*)MYSQLX_TYPE_FLOAT, (double)A +#define PARAM_DOUBLE(A) (void*)MYSQLX_TYPE_DOUBLE, (double)A +#define PARAM_BYTES(DATA, SIZE) (void*)MYSQLX_TYPE_BYTES, (void*)DATA, (size_t)SIZE +#define PARAM_STRING(A) (void*)MYSQLX_TYPE_STRING, A +#define PARAM_EXPR(A) (void*)MYSQLX_TYPE_EXPR, A +#define PARAM_NULL() (void*)MYSQLX_TYPE_NULL + +#define PARAM_END (void*)0 + + +/** + Sort directions in sorting operations such as ORDER BY. +*/ + +typedef enum mysqlx_sort_direction_enum +{ + SORT_ORDER_ASC = 1, /**< Ascending sorting (Default)*/ + SORT_ORDER_DESC = 2 /**< Descending sorting*/ +} mysqlx_sort_direction_t; + + +#define PARAM_SORT_ASC(A) A, SORT_ORDER_ASC +#define PARAM_SORT_DESC(A) A, SORT_ORDER_DESC + +/** + Client options for use with `mysqlx_session_option_get()` + and `mysqlx_session_option_set()` functions. + +*/ + +typedef enum mysqlx_client_opt_type_enum +{ + +#define XAPI_CLIENT_OPT_ENUM_str(X,N) MYSQLX_CLIENT_OPT_##X = -N, +#define XAPI_CLIENT_OPT_ENUM_bool(X,N) MYSQLX_CLIENT_OPT_##X = -N, +#define XAPI_CLIENT_OPT_ENUM_num(X,N) MYSQLX_CLIENT_OPT_##X = -N, +#define XAPI_CLIENT_OPT_ENUM_any(X,N) MYSQLX_CLIENT_OPT_##X = -N, + + CLIENT_OPTION_LIST(XAPI_CLIENT_OPT_ENUM) +} +mysqlx_client_opt_type_t; + +#define OPT_POOLING(A) MYSQLX_CLIENT_OPT_POOLING, (int)(bool)(A) +#define OPT_POOL_MAX_SIZE(A) MYSQLX_CLIENT_OPT_POOL_MAX_SIZE, (uint64_t)(A) +#define OPT_POOL_QUEUE_TIMEOUT(A) MYSQLX_CLIENT_OPT_POOL_QUEUE_TIMEOUT, (uint64_t)(A) +#define OPT_POOL_MAX_IDLE_TIME(A) MYSQLX_CLIENT_OPT_POOL_MAX_IDLE_TIME, (uint64_t)(A) + +/** + Session options for use with `mysqlx_session_option_get()` + and `mysqlx_session_option_set()` functions. + + @note Specifying `MYSQLX_OPT_SSL_CA` option requires `MYSQLX_OPT_SSL_MODE` + value of `SSL_MODE_VERIFY_CA` or `SSL_MODE_VERIFY_IDENTITY`. + If `MYSQLX_OPT_SSL_MODE` is not explicitly given then setting + `MYSQLX_OPT_SSL_CA` implies `SSL_MODE_VERIFY_CA`. + + \anchor opt_session +*/ + +typedef enum mysqlx_opt_type_enum +{ + +#define XAPI_OPT_ENUM_str(X,N) MYSQLX_OPT_##X = N, +#define XAPI_OPT_ENUM_num(X,N) MYSQLX_OPT_##X = N, +#define XAPI_OPT_ENUM_any(X,N) MYSQLX_OPT_##X = N, +#define XAPI_OPT_ENUM_bool(X,N) MYSQLX_OPT_##X = N, + + SESSION_OPTION_LIST(XAPI_OPT_ENUM) + MYSQLX_OPT_LAST +} +mysqlx_opt_type_t; + +#define OPT_HOST(A) MYSQLX_OPT_HOST, (A) +#define OPT_PORT(A) MYSQLX_OPT_PORT, (unsigned int)(A) +#ifndef _WIN32 +#define OPT_SOCKET(A) MYSQLX_OPT_SOCKET, (A) +#endif //_WIN32 +#define OPT_DNS_SRV(A) MYSQLX_OPT_DNS_SRV, (A) +#define OPT_USER(A) MYSQLX_OPT_USER, (A) +#define OPT_PWD(A) MYSQLX_OPT_PWD, (A) +#define OPT_DB(A) MYSQLX_OPT_DB, (A) +#define OPT_SSL_MODE(A) MYSQLX_OPT_SSL_MODE, (A) +#define OPT_SSL_CA(A) MYSQLX_OPT_SSL_CA, (A) +#define OPT_SSL_CAPATH(A) MYSQLX_OPT_SSL_CAPATH, (A) +#define OPT_SSL_CRL(A) MYSQLX_OPT_SSL_CRL, (A) +#define OPT_SSL_CRLPATH(A) MYSQLX_OPT_SSL_CRLPATH, (A) +#define OPT_PRIORITY(A) MYSQLX_OPT_PRIORITY, (unsigned int)(A) +#define OPT_AUTH(A) MYSQLX_OPT_AUTH, (unsigned int)(A) +#define OPT_CONNECT_TIMEOUT(A) MYSQLX_OPT_CONNECT_TIMEOUT, (unsigned int)(A) +#define OPT_CONNECTION_ATTRIBUTES(A) MYSQLX_OPT_CONNECTION_ATTRIBUTES, (A) +#define OPT_TLS_VERSIONS(A) MYSQLX_OPT_TLS_VERSIONS, (A) +#define OPT_TLS_CIPHERSUITES(A) MYSQLX_OPT_TLS_CIPHERSUITES, (A) +#define OPT_COMPRESSION(A) MYSQLX_OPT_COMPRESSION, (unsigned int)(A) +#define OPT_COMPRESSION_ALGORITHMS(A) MYSQLX_OPT_COMPRESSION_ALGORITHMS, (const char*)(A) + + +/** + Session SSL mode values for use with `mysqlx_session_option_get()` + and `mysqlx_session_option_set()` functions setting or getting + MYSQLX_OPT_SSL_MODE option. +*/ + +typedef enum mysqlx_ssl_mode_enum +{ +#define XAPI_SSL_MODE_ENUM(X,N) SSL_MODE_##X = N, + + SSL_MODE_LIST(XAPI_SSL_MODE_ENUM) +} +mysqlx_ssl_mode_t; + +/** + Authentication method values for use with `mysqlx_session_option_get()` + and `mysqlx_session_option_set()` functions setting or getting + MYSQLX_OPT_AUTH option. +*/ + +typedef enum mysqlx_auth_method_enum +{ +#define XAPI_AUTH_ENUM(X,N) MYSQLX_AUTH_##X = N, + + AUTH_METHOD_LIST(XAPI_AUTH_ENUM) +} +mysqlx_auth_method_t; + +/** + Collection create/modify options + + \anchor opt_collection +*/ + +typedef enum mysqlx_collection_opt_enum +{ + +#define XAPI_COLLECTION_OPT_ENUM(X,N) MYSQLX_OPT_COLLECTION_##X = N, + + COLLECTION_OPTIONS_OPTION(XAPI_COLLECTION_OPT_ENUM) + MYSQLX_OPT_COLLECTION_LAST +} +mysqlx_collection_opt_t; + +/** + Collection validation options + + \anchor opt_collection_validation +*/ + +typedef enum mysqlx_collection_validation_opt_enum +{ + +#define XAPI_COLLECTION_VALIDATION_OPT_ENUM(X,N) MYSQLX_OPT_COLLECTION_VALIDATION_##X = 1024+N, + + COLLECTION_VALIDATION_OPTION(XAPI_COLLECTION_VALIDATION_OPT_ENUM) + MYSQLX_OPT_COLLECTION_VALIDATION_LAST +} +mysqlx_collection_validation_opt_t; + +/** + Collection validation level options + \anchor opt_collection_validation_level +*/ + +typedef enum mysqlx_collection_validation_level_enum +{ + +#define XAPI_COLLECTION_VALIDATION_LEVEL_ENUM(X,N) MYSQLX_OPT_COLLECTION_VALIDATION_LEVEL_##X = 2048+N, + + COLLECTION_VALIDATION_LEVEL(XAPI_COLLECTION_VALIDATION_LEVEL_ENUM) + MYSQLX_OPT_COLLECTION_VALIDATION_LEVEL_LAST +} +mysqlx_collection_validation_level_t; + +#define VALIDATION_OFF MYSQLX_OPT_COLLECTION_VALIDATION_LEVEL_OFF +#define VALIDATION_STRICT MYSQLX_OPT_COLLECTION_VALIDATION_LEVEL_STRICT + +#define OPT_COLLECTION_REUSE(X) MYSQLX_OPT_COLLECTION_REUSE, (unsigned int)X +#define OPT_COLLECTION_VALIDATION(X) MYSQLX_OPT_COLLECTION_VALIDATION, (const char*)X +#define OPT_COLLECTION_VALIDATION_LEVEL(X) MYSQLX_OPT_COLLECTION_VALIDATION_LEVEL, (unsigned int)X +#define OPT_COLLECTION_VALIDATION_SCHEMA(X) MYSQLX_OPT_COLLECTION_VALIDATION_SCHEMA, (const char*)X + +/** + Compression modes. + TODO: see... +*/ +typedef enum mysqlx_compression_mode_enum +{ +#define XAPI_COMPRESSION_ENUM(X,N) MYSQLX_COMPRESSION_##X = N, + + COMPRESSION_MODE_LIST(XAPI_COMPRESSION_ENUM) +} +mysqlx_compression_mode_t; + +/** + Constants for defining the row locking options for + mysqlx_set_row_locking() function. + @see https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html +*/ +typedef enum mysqlx_row_locking_enum +{ +#define XAPI_ROW_LOCK_ENUM(X,N) ROW_LOCK_##X = N, + + ROW_LOCK_NONE = 0, /**< No locking */ + LOCK_MODE_LIST(XAPI_ROW_LOCK_ENUM) +} +mysqlx_row_locking_t; + +/** + Constants for defining the row locking options for + mysqlx_set_row_locking() function. + @see https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html#innodb-locking-reads-nowait-skip-locked +*/ +typedef enum mysqlx_lock_contention_enum +{ +#define XAPI_LOCK_CONTENTION_ENUM(X,N) LOCK_CONTENTION_##X = N, + + LOCK_CONTENTION_LIST(XAPI_LOCK_CONTENTION_ENUM) +} +mysqlx_lock_contention_t; + +/* + ==================================================================== + Client operations + ==================================================================== +*/ + +/** + Create a client instance using connection string or URL and a client options + JSON. + + Connection sting has the form `"user:pass@host:port/?option&option"`, + valid URL is like a connection string with a `mysqlx://` prefix. Host is + specified as either DNS name, IPv4 address of the form "nn.nn.nn.nn" or + IPv6 address of the form "[nn:nn:nn:...]". + + Possible connection options are: + + - `ssl-mode` : TLS connection mode + - `ssl-ca=`path : path to a PEM file specifying trusted root certificates + + Specifying `ssl-ca` option implies `ssl-mode=VERIFY_CA`. + + Client options are expressed in a JSON string format. Here is an example: + ~~~~~~ + { "pooling": { + "enabled": true, + "maxSize": 25, + "queueTimeout": 1000, + "maxIdleTime": 5000} + } + ~~~~~~ + + All options are defined under a document with key vale "pooling". Inside the + document, the available options are these: + - `enabled` : boolean value that enable or disable connection pooling. If + disabled, session created from pool are the same as created + directly without client handle. + Enabled by default. + - `maxSize` : integer that defines the max pooling sessions possible. If uses + tries to get session from pool when maximum sessions are used, + it will wait for an available session untill `queueTimeout`. + Defaults to 25. + - `queueTimeout` : integer value that defines the time, in milliseconds, that + client will wait to get an available session. + By default it doesn't timeouts. + - `maxIdleTime` : integer value that defines the time, in milliseconds, that + an available session will wait in the pool before it is + removed. + By default it doesn't cleans sessions. + + @param conn_string connection string + @param client_opts client options in the form of a JSON string. + @param[out] error if error happens during connect the error object + is returned through this parameter + + @return client handle if client could be created, otherwise NULL + is returned and the error information is returned through + the error output parameter. + + @note The client returned by the function must be properly closed using + `mysqlx_client_close()`. + + @note If an error object returned through the output parameter it must be + freed using `mysqlx_free()`. + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_client_t * +mysqlx_get_client_from_url(const char *conn_string, const char *client_opts, + mysqlx_error_t **error); + + +/** + Create a client pool using session configuration data. + + Client options are expressed in a JSON string format. Here is an example: + ~~~~~~ + { "pooling": { + "enabled": true, + "maxSize": 25, + "queueTimeout": 1000, + "maxIdleTime": 5000} + } + ~~~~~~ + + All options are defined under a document with key vale "pooling". Inside the + document, the available options are these: + - `enabled` : boolean value that enable or disable connection pooling. If + disabled, session created from pool are the same as created + directly without client handle. + Enabled by default. + - `maxSize` : integer that defines the max pooling sessions possible. If uses + tries to get session from pool when maximum sessions are used, + it will wait for an available session untill `queueTimeout`. + Defaults to 25. + - `queueTimeout` : integer value that defines the time, in milliseconds, that + client will wait to get an available session. + By default it doesn't timeouts. + - `maxIdleTime` : integer value that defines the time, in milliseconds, that + an available session will wait in the pool before it is + removed. + By default it doesn't cleans sessions. + + @param opt handle to client configuration data + @param[out] error if error happens during connect the error object + is returned through this parameter + + @return client handle if client could be created, otherwise NULL + is returned and the error information is returned through + the error output parameter. + + @note The client returned by the function must be properly closed using + `mysqlx_client_close()`. + + @note If an error object returned through the output parameter it must be + freed using `mysqlx_free()`. + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_client_t * +mysqlx_get_client_from_options(mysqlx_session_options_t *opt, + mysqlx_error_t **error); + +/** + Close the client pool and all sessions created by them. + + This function must be called by the user to prevent memory leaks. + Closing client closes all sessions created by this client.\n + Sessions created by this client are closed, but their resources are not freed. + `mysqlx_session_close()` has to be called to prevent memory leaks. + + After a call to this function the given client handle becomes invalid. + Any attempt to use the handle after this, results in undefined behavior. + + + @param client client handle + + @ingroup xapi_sess +*/ + +PUBLIC_API void mysqlx_client_close(mysqlx_client_t *client); + +/* + ==================================================================== + Session operations + ==================================================================== +*/ + +/** + Create a new session + + @param cli client pool to get session from + @param[out] error if error happens during connect the error object + is returned through this parameter + + @note If an error object returned through the output parameter it must be + freed using `mysqlx_free()`. +*/ + +PUBLIC_API mysqlx_session_t * +mysqlx_get_session_from_client(mysqlx_client_t *cli, + mysqlx_error_t **error); + +/** + Create a new session. + + @param host server host DNS name, IPv4 address or IPv6 address + @param port port number + @param user user name + @param password password + @param database default database name + @param[out] error if error happens during connect the error object + is returned through this parameter + + @return session handle if session could be created, otherwise NULL + is returned and the error information is returned through + output error parameter. + + @note The session returned by the function must be properly closed using + `mysqlx_session_close()`. + @note This function always establishes connection with SSL enabled + @note If an error object returned through the output parameter it must be + freed using `mysqlx_free()`. + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_session_t * +mysqlx_get_session(const char *host, int port, const char *user, + const char *password, const char *database, + mysqlx_error_t **error); + + +/** + Create a session using connection string or URL. + + @param conn_string connection string + @param[out] error if error happens during connect the error object + is returned through this parameter + + @return session handle if session could be created, otherwise NULL + is returned and the error information is returned through + the error output parameter. + + + Connection sting has the form + + "user:pass@connection-data/db?option&option" + + with optional `mysqlx://` prefix. + + The `connetction-data` part is either a single host address or a coma + separated list of hosts in square brackets: `[host1, host2, ..., hostN]`. + In the latter case the connection fail-over logic will be used when + creating the session. + + A single host address is either a DNS host name, an IPv4 address of + the form `nn.nn.nn.nn` or an IPv6 address of the form `[nn:nn:nn:...]`. + On Unix systems a host can be specified as a path to a Unix domain + socket - this path must start with `/` or `.`. + + Characters like `/` in the connection data, which otherwise have a special + meaning inside a connection string, must be represented using percent + encoding (e.g., `%2F` for `/`). Another option is to enclose a host name or + a socket path in round braces. For example, one can write + + "mysqlx://(./path/to/socket)/db" + + instead of + + "mysqlx://.%2Fpath%2Fto%2Fsocket/db" + + To specify priorities for hosts in a multi-host settings, use list of pairs + of the form `(address=host,priority=N)`. If priorities are specified, they + must be given to all hosts in the list. + + The optional `db` part of the connection string defines the default schema + of the session. + + Possible connection options are: + + - `ssl-mode=...` : see `#MYSQLX_OPT_SSL_MODE`; the value is a case insensitive + name of the SSL mode + - `ssl-ca=...` : see `#MYSQLX_OPT_SSL_CA` + - `auth=...`: see `#MYSQLX_OPT_AUTH`; the value is a case insensitive name of + the authentication method + - `connect-timeout=...`: see `#MYSQLX_OPT_CONNECT_TIMEOUT` + - `connection-attributes=[...]` : see `#MYSQLX_OPT_CONNECTION_ATTRIBUTES` + but the key-value pairs are not given by a JSON document but as a list;\n + Examples:\n + `"mysqlx://user@host?connection-attributes=[foo=bar,qux,baz=]"` - + specify additional attributes to be sent\n + `"mysqlx://user@host?connection-attributes=false"` - + send no connection attributes\n + `"mysqlx://user@host?connection-attributes=true"` - + send default connection attributes\n + `"mysqlx://user@host?connection-attributes=[]"` - + the same as setting to `true`\n + `"mysqlx://user@host?connection-attributes"` - + the same as setting to `true`\n + - `tls-versions=[...]` : see `#MYSQLX_OPT_TLS_VERSIONS` + - `tls-ciphersuites=[...]` : see `#MYSQLX_OPT_TLS_CIPHERSUITES` + - `compression=...` : see `#MYSQLX_OPT_COMPRESSION` + - `compression-algorithms=[...]` : see `#MYSQLX_OPT_COMPRESSION_ALGORITHMS` + + + @note The session returned by the function must be properly closed using + `mysqlx_session_close()`. + @note If an error object returned through the output parameter it must be + freed using `mysqlx_free()`. + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_session_t * +mysqlx_get_session_from_url(const char *conn_string, + mysqlx_error_t **error); + +/** + Create a session using session configuration data. + + @param opt handle to session configuration data + @param[out] error if error happens during connect the error object + is returned through this parameter + + @return session handle if session could be created, otherwise NULL + is returned and the error information is returned through + the error output parameter. + + @note The session returned by the function must be properly closed using + `mysqlx_session_close()`. + @note If an error object returned through the output parameter it must be + freed using `mysqlx_free()`. + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_session_t * +mysqlx_get_session_from_options(mysqlx_session_options_t *opt, + mysqlx_error_t **error); + + + +/** + Close the session. + + This function must be called by the user to prevent memory leaks. + Closing session frees all related resources, including those + allocated by statements and results belonging to the session. + + After a call to this function the given session handle becomes invalid. + Any attempt to use the handle after this, results in undefined behavior. + + @param session session handle + + @ingroup xapi_sess +*/ + +PUBLIC_API void mysqlx_session_close(mysqlx_session_t *session); + + +/** + Check the session validity. + + @param sess session handle + + @return 1 - if the session is valid, 0 - if the session is not valid + + @note The function checks only the internal session status without + communicating with server(s). + + @note This function cannot be called for a session that was closed, + because in this case the session handle itself is invalid and + cannot be used in API calls. + + @ingroup xapi_sess +*/ + +PUBLIC_API int mysqlx_session_valid(mysqlx_session_t *sess); + +/** + Get a list of schemas. + + The result is returned as a set of rows with one column containing schema + name. The rows can be read with functions such as `mysqlx_row_fetch_one()`, + `mysqlx_store_result()` etc. + + @param sess session handle + @param schema_pattern schema name pattern to search, using "%" as a wildcard + character; if this parameter is NULL then all schemas will be + returned. + + @return handle to the result with rows containing schema names. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_get_schemas(mysqlx_session_t *sess, const char *schema_pattern); + + +/** + Get a schema object and optionally check if it exists on the server. + + @param sess session handle + @param schema_name name of the schema + @param check flag to verify if the schema with the given name + exists on the server (1 - check, 0 - do not check) + + @return handle to the schema object or NULL + if an error occurred or the schema does not exist on the server + + @note Performing existence check involves communication with server(s). + Without the check, this operation is executed locally. It is then possible + to create a handle to a non-existent schema. Attempt to use such + a handle later would eventually trigger an error. + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_schema_t * +mysqlx_get_schema(mysqlx_session_t *sess, const char *schema_name, + unsigned int check); + + +/** + Get a list of tables and views in a schema. + + The result is returned as a set of rows with two columns. The first column + contains table/view name, the second column contains object type, either + "TABLE" or "VIEW". The rows can be read with functions such as + `mysqlx_row_fetch_one()`, `mysqlx_store_result()` etc. + + @param schema schema handle + @param table_pattern table name pattern to search, using "%" as a wildcard + character; if this parameter is NULL then all tables/views in the + given schema will be returned. + @param get_views flag specifying whether view names should be included + into the result. 0 - do not show views (only table names are in + the result), 1 - show views (table and view names are in the result) + + @return handle to the result with rows containing table/view names. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @note this function does not return names of tables that represent + collections, use `mysqlx_get_collections()` function for getting + collections. + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_get_tables(mysqlx_schema_t *schema, + const char *table_pattern, + int get_views); + + +/** + Get a table object and optionally check if it exists in the schema + + @param schema schema handle + @param tab_name name of the table + @param check flag to verify if the table with the given name + exists in the schema (1 - check, 0 - do not check) + + @return handle to the table or NULL + if an error occurred or the table does not exist in the schema + + @note Performing existence check involves communication with server(s). + Without the check, this operation is executed locally. It is then possible + to create a handle to a non-existent table. Attempt to use such + a handle later would eventually trigger an error. + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_table_t * +mysqlx_get_table(mysqlx_schema_t *schema, const char *tab_name, + unsigned int check); + + +/** + Get a list of collections in a schema. + + The result is returned as a set of rows with two columns. The first column + contains collection name and the second column contains string "COLLECTION". + The rows can be read with functions such as `mysqlx_row_fetch_one()`, + `mysqlx_store_result()` etc. + + @param schema handle + @param col_pattern collection name pattern to search, using "%" as a wildcard + character; if this parameter is NULL then all collections in the given + schema will be returned. + + @return handle to the result with rows containing collection names. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_get_collections(mysqlx_schema_t *schema, + const char *col_pattern); + + +/** + Get a collection object and optionally check if it exists in the schema + + @param schema schema handle + @param col_name name of the collection + @param check flag to verify if the collection with the given name + exists in the schema (1 - check, 0 - do not check) + + @return handle to the collection or NULL + if an error occurred or the collection does not exist in the schema + + @note Performing existence check involves communication with server(s). + Without the check, this operation is executed locally. It is then possible + to create a handle to a non-existent collection. Attempt to use such + a handle later would eventually trigger an error. + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_collection_t * +mysqlx_get_collection(mysqlx_schema_t *schema, const char *col_name, + unsigned int check); + + +/** + Begin a transaction for the session. + + @param sess session handle + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note a statement will belong to the transaction when + it is actually executed after the transaction began (and before + it is committed or rolled back) even if this statement + was created before `mysqlx_transaction_begin()` call + + @ingroup xapi_sess +*/ + +PUBLIC_API int +mysqlx_transaction_begin(mysqlx_session_t *sess); + + +/** + Commit a transaction for the session. + + @param sess session handle + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note This will commit all statements that were executed as part of this + transaction, regardless of when the statements were created (see + `mysqlx_transaction_begin()`). + + @ingroup xapi_sess +*/ + +PUBLIC_API int +mysqlx_transaction_commit(mysqlx_session_t *sess); + + +/** + Roll back a transaction for the session. + + @param sess session handle + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note This will roll back all statements that were executed as part of this + transaction, regardless of when the statements were created (see + `mysqlx_transaction_begin()`). + + @ingroup xapi_sess +*/ + +PUBLIC_API int +mysqlx_transaction_rollback(mysqlx_session_t *sess); + + +/** + Create savepoint inside transaction. + + @param sess session handle. + + @param name savepoint name (NULL for automatically generated one) + + @return savepoint name + + @note Savepoints are created inside transaction! Later, you can roll back + the transaction to a created savepoint using mysqlx_rollback_to(). + If the current transaction has a savepoint with the same name, the old + savepoint is deleted and a new one is set. + + @ingroup xapi_sess +*/ + +PUBLIC_API const char* +mysqlx_savepoint_set( mysqlx_session_t *sess, const char *name); + + +/** + Release savepoint created by mysqlx_savepoint_set(). + + @param sess session handle + + @param name savepoint name to be released + + @return `RESULT_OK` - savepoint exists and is released; + `RESULT_ERROR` - on error + + @ingroup xapi_sess +*/ + +PUBLIC_API int +mysqlx_savepoint_release(mysqlx_session_t *sess, const char *name); + + +/** + Roll back to savepoint created by mysqlx_savepoint_set(). + + @param sess session handle. + + @param name savepoint name. + + @return `RESULT_OK` - savepoint exists and is released; + `RESULT_ERROR` - on error. + + @ingroup xapi_sess +*/ + +PUBLIC_API int +mysqlx_rollback_to( mysqlx_session_t *sess, const char *name); + + +/** + Allocate a new session configuration data object. + + @return handle to the newly allocated configuration data + + @note The allocated object must be eventually freed by + `mysqlx_free()` to prevent memory leaks + + @ingroup xapi_sess +*/ + +PUBLIC_API mysqlx_session_options_t * mysqlx_session_options_new(); + + +/** + Free a session configuration data object. + + @param opt handle to sessin configuartion data object + that has to be freed + + @note This function is DEPRECATED. Use `mysqlx_free()` instead. + + @ingroup xapi_sess +*/ + +PUBLIC_API void mysqlx_free_options(mysqlx_session_options_t *opt); + + +/** + Set session configuration options. + + @param opth handle to session configuration data object + @param ... variable parameters list consisting of (option, value) pairs + terminated by `PARAM_END`. + + @return `RESULT_OK` if option was successfully set; `RESULT_ERROR` + is set otherwise (use `mysqlx_error()` to get the error + information) + + The variable parameter list is of the form + + OPT_O1(val1), OPT_O2(val2), ..., OPT_On(valn), PARAM_END + + or, equivalently, + + MYSQLX_OPT_O1, val1, ..., MYSQLX_OPT_On, valn, PARAM_END + + Possible options are defined by enumeration + \ref opt_session "mysqlx_opt_type_t". Type of option value `vali` (number, + string, etc.) must match the option `MYSQLX_OPT_Oi`, otherwise this value + along with all the sequential options and values are most likely + to be corrupted. + + @ingroup xapi_sess +*/ + +PUBLIC_API int +mysqlx_session_option_set(mysqlx_session_options_t *opth, ...); + + +/** + Read session configuration options. + + @param opth handle to session configuration data object + @param opt option whose value to read (see + \ref opt_session "mysqlx_opt_type_t") + @param[out] ... pointer to a buffer where to return the requested + value + + TODO: Point to documentation explaining what data is returned for + each option. + + @return `RESULT_OK` if option was successfully read; `RESULT_ERROR` + is set otherwise (use `mysqlx_error()` to get the error + information) + + @note When reading string option values to a bufer, user is responsible for + providing a large enough buffer. No overrun checks are done when + copying data to the buffer. + + @note For failover configurations with multiple hosts this function + will return only the last added host name. Same is true for the port + or the priority associated with this host name. + + @ingroup xapi_sess +*/ + +PUBLIC_API int +mysqlx_session_option_get(mysqlx_session_options_t *opth, int opt, + ...); + +/* + ==================================================================== + SQL execution + ==================================================================== +*/ + +/** + Execute a plain SQL query. + + @param sess session handle + @param query SQL query + @param query_len length of the query. For NULL-terminated query strings + `MYSQLX_NULL_TERMINATED` can be specified instead of the + actual length + + @return handle to the query results. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_sql +*/ + +PUBLIC_API mysqlx_result_t * mysqlx_sql(mysqlx_session_t *sess, + const char *query, + size_t query_len); + + +/** + Execute a plain SQL query with parameters. + + @param sess session handle + @param query SQL query + @param query_len length of the query. For NULL-terminated query strings + `MYSQLX_NULL_TERMINATED` can be specified instead of the + actual length + @param ... variable parameters list consisting of (type, value) pairs + terminated by `PARAM_END`: type_id1, value1, type_id2, value2, ..., + type_id_n, value_n, `PARAM_END` (`PARAM_END` marks the end of + the parameters list). + + type_id is the numeric identifier, which helps to determine the type + of the value provided as the next parameter. The user code must + ensure that type_id corresponds to the actual value type. Otherwise, + the value along with and all sequential types and values are most + likely to be corrupted. + Allowed types are listed in `mysqlx_data_type_t` enum. + The X DevAPI for C defines the convenience macros that help to specify + the types and values: See `PARAM_SINT()`, `PARAM_UINT()`, + `PARAM_FLOAT()`, `PARAM_DOUBLE()`, `PARAM_BYTES()`, + `PARAM_STRING()`. + + @return handle to the query results. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_sql +*/ + +PUBLIC_API mysqlx_result_t * mysqlx_sql_param(mysqlx_session_t *sess, + const char *query, + size_t query_len, ...); + + +/** + Create a statement which executes a plain SQL query. + + @note The query can contain `?` placeholders whose values should be + specified using `mysqlx_stmt_bind()` function before executing + the statement. + + @param sess session handle + @param query SQL query + @param length length of the query + + @return statement handle containing the results and/or error. + NULL can be returned only in case when there are problems + allocating memory, which normally should not happen. + It is very unlikely for this function to end with an error + because it does not do any parsing, parameter checking etc. + + @note To actually execute the SQL query the returned statement has to be + given to `mysqlx_execute()`. + + @see mysqlx_stmt_bind() + + @ingroup xapi_sql +*/ + +PUBLIC_API mysqlx_stmt_t * +mysqlx_sql_new(mysqlx_session_t *sess, const char *query, + uint32_t length); + + +/* + ==================================================================== + Collection operations + ==================================================================== +*/ + +/** + Return a number of documents in a collection. + + @param collection collection handle + @param[out] count the number of documents in a given collection + is returned through the parameter + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @ingroup xapi_coll +*/ + +PUBLIC_API int +mysqlx_collection_count(mysqlx_collection_t *collection, uint64_t *count); + + +/** + Execute a collection FIND statement with a specific find + criteria. + + @param collection collection handle + @param criteria criteria for finding documents; if this parameter is + NULL then all documents are returned + + @return handle to the query results. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_collection_find(mysqlx_collection_t *collection, const char *criteria); + + +/** + Add a set of new documents to a collection. + + Each document is defined by a JSON string like + "{ \"key_1\\": value_1, ..., \"key_N\\": value_N }" + + @param collection collection handle + @param ... list of parameters containing the character JSON strings + describing documents to be added. Each parameter + is a separate document. The list has to be terminated by + PARAM_END macro + + @return handle to the statement result. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + Each document must have a unique identifier which is stored in `_id` + field of the document. Document identifiers are character strings no longer + than 32 characters. If added document does not have `_id` field, a unique + identifier will be generated for it. Document identifier generated by given + collection add operation can be examined using `mysqlx_fetch_generated_id()` + function. Generated document identifiers are strings of 32 hexadecimal digits, + like this one `0512020981044082E6119DFA0E4C0584`. + + @note Generated document identifiers are based on UUIDs but they are not + valid UUIDs (fields are reversed). + + @see `mysqlx_collection_add_new()` + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_collection_add(mysqlx_collection_t *collection, ...); + + +/** + Remove documents from a collection. + + @param collection collection handle + @param criteria criteria selecting documents to be removed; if this parameter + is NULL, all documents are removed + + @return handle to the statement result. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_collection_remove(mysqlx_collection_t *collection, const char*criteria); + + +/** + Modify documents in the collection. + + @param collection collection handle + @param criteria criteria selecting documents to be modified; if this + parameter is NULL then all documents are modified + @param ... list of parameters that come as triplets + + Each triplet specifies a field inside a document that should + be modified (field_path) and the new value for that field. + The value_type is the type identifier + for the data type of value (see `mysqlx_data_type_t` enum) + The list is terminated by `PARAM_END`. + For `MYSQLX_TYPE_BYTES` there will be one extra parameter specifying + the length of the binary data: + + The X DevAPI for C defines the convenience macros that help to specify + the types and values: See `PARAM_SINT()`, `PARAM_UINT()`, + `PARAM_FLOAT()`, `PARAM_DOUBLE()`, `PARAM_BYTES()`, + `PARAM_STRING()`, `PARAM_EXPR()`: + + ..., "a_key", PARAM_STRING("New Text Value"), + "b_key", PARAM_EXPR("b_key-1000"), + PARAM_END + + @return handle to the statement result + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_collection_modify_set(mysqlx_collection_t *collection, + const char *criteria, ...); + + +/** + Unset fields in documents from the collection. + + @param collection collection handle + @param criteria criteria selecting documents to be modified; if this + parameter is NULL then all documents are modified + @param ... list of field paths that should be unset; + The list end is marked using `PARAM_END` + + @return handle to the statement result. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_collection_modify_unset(mysqlx_collection_t *collection, + const char *criteria, ...); + + +/** + Apply a given patch to documents in a collection. + + @param collection collection handle + @param criteria criteria selecting documents to be modified; if this + parameter is NULL then all documents are modified + @param patch_spec patch specification given as a character string and + interpreted like a JSON documents, but values of fields are + interpreted as expressions + + @return handle to the statement result. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_collection_modify_patch(mysqlx_collection_t *collection, + const char *criteria, + const char *patch_spec); + + +/** + Set a given patch for a modify statement to be applied to + documents in a collection after executing the statement. + + @param stmt modify statement + @param patch_spec patch specification given as a character string and + interpreted like a JSON documents, but values of fields are + interpreted as expressions + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + @ingroup xapi_coll +*/ + +PUBLIC_API int +mysqlx_set_modify_patch(mysqlx_stmt_t *stmt, + const char *patch_spec); + +/* + Deferred statement execution + ---------------------------- +*/ + +/** + Create a statement which finds documents in a collection + + @param collection collection handle + + @return handle for the newly created FIND statement. + NULL can be returned only in case when there are problems + allocating memory, which normally should not happen. + It is very unlikely for this function to end with an error + because it does not do any parsing, parameter checking etc. + + @note To actually execute the operation, use `mysqlx_execute()`. + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_stmt_t * +mysqlx_collection_find_new(mysqlx_collection_t *collection); + + +/** + Specify a projection for a collection find query + + The projection, if present, specifies mapping from documents found by the + query to new documents returned in the final result. + + @param stmt statement handle + @param proj projection specification describing JSON document projections as + "{ \"proj1\\": expr1, ..., \"projN\\": exprN }". Expressions used + in the projection can refer to fields in the original document + using `$.path.to.field` syntax. + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note This function can be only called for the collection FIND statements + @see mysqlsx_collection_find_new() + + @ingroup xapi_coll +*/ + +PUBLIC_API int mysqlx_set_find_projection(mysqlx_stmt_t *stmt, const char *proj); + + +/** + A macro defining a function for setting criteria for FIND operation. + + @see mysqlx_set_where() + + @ingroup xapi_coll +*/ + +#define mysqlx_set_find_criteria mysqlx_set_where + + +/* +A macro defining a function for setting HAVING for FIND operation. + +@see mysqlx_set_having() +@ingroup xapi_tbl +*/ + +#define mysqlx_set_find_having mysqlx_set_having + + +/** +A macro defining a function for setting GROUP BY for FIND operation. + +@see mysqlx_set_group_by() +@ingroup xapi_tbl +*/ + +#define mysqlx_set_find_group_by mysqlx_set_group_by + + +/** + A macro defining a function for setting LIMIT for DELETE operation. + + @see mysqlx_set_limit_and_offset() + @ingroup xapi_coll +*/ + +#define mysqlx_set_find_limit_and_offset(STMT, LIM, OFFS) mysqlx_set_limit_and_offset(STMT, LIM, OFFS) + + +/** + A macro defining a function for setting ORDER BY for SELECT operation. + + @see mysqlx_set_order_by() + @ingroup xapi_coll +*/ + +#define mysqlx_set_find_order_by mysqlx_set_order_by + + +/** + A macro defining a function for setting row locking mode + for FIND operation. + + @see mysqlx_set_row_locking() + @ingroup xapi_coll +*/ + +#define mysqlx_set_find_row_locking mysqlx_set_row_locking + + +/** + Create a statement which adds documents to a collection + + @param collection collection handle + + @return handle for the newly created ADD statement. + NULL can be returned only in case when there are problems + allocating memory, which normally should not happen. + It is very unlikely for this function to end with an error + because it does not do any parsing, parameter checking etc. + + @note To actually execute the operation, use `mysqlx_execute()` after + specifying documents to be added. + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_stmt_t * +mysqlx_collection_add_new(mysqlx_collection_t *collection); + + +/** + Specify a document to be added to a collection. + + The function provides the document data for the ADD statement as + a JSON string like "{ \"key_1\\": value_1, ..., \"key_N\\": value_N }" + User code must ensure the validity of the document because it is + not checked until receiving the query on the server side. + + @note key names and string values in a JSON string must be given + in quotes and such quotes need to be escaped. + + @param stmt statement handle + @param json_doc - the JSON string describing document to add + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note Each new call provides the values for the new document, which + can be used for multi-document add operations. + @note User can provide document id as a value of `_id` field, otherwise + document id is generated by the add operation. Document id must be + a string - setting `_id` to a non-string value triggers + an error. + + @ingroup xapi_coll +*/ + +PUBLIC_API int +mysqlx_set_add_document(mysqlx_stmt_t *stmt, const char *json_doc); + + +/** + Create a statement which removes documents from a collection. + + @param collection collection handle + + @return handle for the newly created REMOVE statement. + NULL can be returned only in case when there are problems + allocating memory, which normally should not happen. + It is very unlikely for this function to end with an error + because it does not do any parsing, parameter checking etc. + + @note To actually execute the statement, use `mysqlx_execute()` + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_stmt_t * +mysqlx_collection_remove_new(mysqlx_collection_t *collection); + + +/** + A macro defining a function for setting WHERE for REMOVE operation. + + @see mysqlx_set_where() + @ingroup xapi_coll +*/ + +#define mysqlx_set_remove_criteria mysqlx_set_where + + +/** + A macro defining a function for setting ORDER BY for REMOVE operation. + + @see mysqlx_set_order_by() + @ingroup xapi_coll +*/ + +#define mysqlx_set_remove_order_by mysqlx_set_order_by + + +/** + A macro defining a function for setting LIMIT for REMOVE operation. + + @see mysqlx_set_limit_and_offset() + @ingroup xapi_coll +*/ + +#define mysqlx_set_remove_limit_and_offset mysqlx_set_limit_and_offset + + +/** + Create a statement which modifies documents in a collection. + + @param collection collection handle + + @return handle for the newly created MODIFY statement. + NULL can be returned only in case when there are problems + allocating memory, which normally should not happen. + It is very unlikely for this function to end with an error + because it does not do any parsing, parameter checking etc. + + @note To actually execute the statement, use `mysqlx_execute()` after + specifying modifications that should be performed. + + @ingroup xapi_coll +*/ + +PUBLIC_API mysqlx_stmt_t * +mysqlx_collection_modify_new(mysqlx_collection_t *collection); + + +/** + Set fields in a document to given values. + + @param stmt handle to MODIFY statement + @param ... list of parameters that come as triplets + + Each triplet represents a value inside a document that can + be located by field_path. The value_type is the type identifier + for the data type of value (see `mysqlx_data_type_t` enum) + The list is terminated by `PARAM_END`. + For `MYSQLX_TYPE_BYTES` there will be one extra parameter specifying + the length of the binary data: + + + @note For the convenience the code can use `PARAM_TTT(val)` macros + instead of (`MYSQLX_TYPE_TTT`, value) pairs (see `mysqlx_stmt_bind()`). + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @ingroup xapi_coll +*/ + +PUBLIC_API int +mysqlx_set_modify_set(mysqlx_stmt_t *stmt, ...); + + +/** + Unset fields in a document + + @param stmt handle to MODIFY statement + @param ... list of paths to the documents fields that should be unset. Each + entry in this list is a character string. + The list is terminated by `PARAM_END`. + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @ingroup xapi_coll +*/ + +PUBLIC_API int +mysqlx_set_modify_unset(mysqlx_stmt_t *stmt, ...); + + +/** + Insert elements into array fields in a document + + @param stmt handle to MODIFY statement + @param ... list of parameters that come as triplets + + Each triplet represents a position in an array field of a document, + given by field_path, and a value to be inserted in that position. + The value_type is the type identifier for the data type of value + (see `mysqlx_data_type_t` enum). The list is terminated by `PARAM_END`. + + @note For the convenience the code can use `PARAM_TTT(val)` macros + instead of (`MYSQLX_TYPE_TTT`, value) pairs (see `mysqlx_stmt_bind()`). + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @ingroup xapi_coll +*/ + +PUBLIC_API int +mysqlx_set_modify_array_insert(mysqlx_stmt_t *stmt, ...); + + +/** + Append to array fields in a document + + @param stmt handle to MODIFY statement + @param ... list of parameters that come as triplets + . Each triplet specifies an array + field in a document, given by field_path, and a value that should + be appended to that array. The value_type is the type identifier + for the data type of value (see `mysqlx_data_type_t` enum). + The list is terminated by `PARAM_END`. + + @note For the convenience the code can use `PARAM_TTT(val)` macros + instead of (`MYSQLX_TYPE_TTT`, value) pairs (see `mysqlx_stmt_bind()`). + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @ingroup xapi_coll +*/ + +PUBLIC_API int +mysqlx_set_modify_array_append(mysqlx_stmt_t *stmt, ...); + + +/** + Delete elements from array fields in a document + + @param stmt handle to MODIFY statement + @param ... list of paths to array elements that should be deleted from their + arrays. The list is terminated by `PARAM_END`. + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @ingroup xapi_coll +*/ + +PUBLIC_API int mysqlx_set_modify_array_delete(mysqlx_stmt_t *stmt, ...); + + +/** + A macro defining a function for setting WHERE for MODIFY operation. + + @see mysqlx_set_where() + @ingroup xapi_coll +*/ + +#define mysqlx_set_modify_criteria mysqlx_set_where + + +/* + ==================================================================== + Table operations + ==================================================================== +*/ + + +/** + Return a number of rows in a table + + @param table table handle + @param[out] count the number of rows in a given table is returned + through the parameter + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @ingroup xapi_coll +*/ + +PUBLIC_API int +mysqlx_table_count(mysqlx_table_t *table, uint64_t *count); + + +/** + Execute a table SELECT statement with a WHERE clause. + + All columns will be selected. + + @param table table handle + @param criteria row selection criteria (WHERE clause); if NULL then + all rows in the table are returned. + + @return handle to the query results + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_tbl +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_table_select(mysqlx_table_t *table, const char *criteria); + + +/** + Execute a table SELECT statement with a WHERE, + ORDER BY and LIMIT clauses + + @param table table handle + @param criteria row selection criteria (WHERE clause); if NULL then all + rows in the table will be selected. + @param row_count a number of rows to return (LIMIT clause) + @param offset number of rows to skip (an offset for the LIMIT clause) + @param ... sorting specification - variable parameters list consisting of + (expression, direction) pairs terminated by `PARAM_END`: expr_1, + direction_1, ..., expr_n, direction_n, `PARAM_END`. + Each expression computes a value used to sort + the rows/documents in ascending or descending order, + as determined by direction constant + (TODO: list the direction enum names). + Special attention must be paid to the expression + strings because the empty string "" or NULL will be treated + as the end of sequence + + @return handle to the query results. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_tbl +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_table_select_limit(mysqlx_table_t *table, const char *criteria, + uint64_t row_count, uint64_t offset, ...); + + +/** + Execute a table INSERT statement with one row. + + @param table table handle + @param ... list of column-value specifications consisting of + triplets. The list + should be terminated using `PARAM_END`. + Allowed value types are listed in `mysqlx_data_type_t` enum. + The X DevAPI for C defines the convenience macros that help + to specify the types and values: See `PARAM_SINT()`, + `PARAM_UINT()`, `PARAM_FLOAT()`, `PARAM_DOUBLE()`, `PARAM_BYTES()`, + `PARAM_STRING()`: + + ..., "col_uint", PARAM_UINT(uint_val), + "col_blob", PARAM_BYTES(byte_buf, buf_len), + PARAM_END + + @return handle to the query results. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_tbl +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_table_insert(mysqlx_table_t *table, ...); + + +/** + Execute a table DELETE statement with a WHERE clause. + + @param table table handle + @param criteria expression selecting rows to be deleted; if this + parameter is NULL all rows are deleted + + @return handle to the query results. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_tbl +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_table_delete(mysqlx_table_t *table, const char *criteria); + + + +/** + Execute a table UPDATE statement. + + @param table table handle + @param criteria expression selecting rows to be updated (WHERE clause) + @param ... list of column-value specifications consisting of + triplets. The list + should be terminated using `PARAM_END`. + Allowed value types are listed in `mysqlx_data_type_t` enum. + The X DevAPI for C defines the convenience macros that help + to specify the types and values: See `PARAM_SINT()`, + `PARAM_UINT()`, `PARAM_FLOAT()`, `PARAM_DOUBLE()`, `PARAM_BYTES()`, + `PARAM_STRING()`, `PARAM_EXPR()`: + + ..., "col_uint", PARAM_EXPR("col_uint * 100"), + "col_blob", PARAM_BYTES(byte_buf, buf_len), + PARAM_END + + @return handle to the query results. + NULL is returned only in case of an error. The error details + can be obtained using `mysqlx_error()` function + + @ingroup xapi_tbl +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_table_update(mysqlx_table_t *table, + const char *criteria, + ...); + + +/* + Deferred statement execution + ---------------------------- +*/ + +/** + Create a statement which performs a table SELECT operation. + + @param table table handle + + @return handle to the newly created SELECT statement. + NULL can be returned only in case when there are problems + allocating memory, which normally should not happen. + It is very unlikely for this function to end with an error + because it does not do any parsing, parameter checking etc. + + @note To actually execute the statement, the returned handle has to be + given to `mysqlx_execute()`. + + @see mysqlx_set_insert_columns(), mysqlx_set_insert_row() + + @ingroup xapi_tbl +*/ + +PUBLIC_API mysqlx_stmt_t * +mysqlx_table_select_new(mysqlx_table_t *table); + + +/** + A macro defining a function for setting projections for SELECT operation. + + @see mysqlx_set_items() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_select_items mysqlx_set_items + + +/** + A macro defining a function for setting WHERE for SELECT operation. + + @see mysqlx_set_where() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_select_where mysqlx_set_where + + +/** + A macro defining a function for setting ORDER BY for SELECT + operation. + + @see mysqlx_set_order_by() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_select_order_by mysqlx_set_order_by + + +/* + A macro defining a function for setting HAVING for SELECT operation. + + @see mysqlx_set_having() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_select_having mysqlx_set_having + + +/** +A macro defining a function for setting GROUP BY for SELECT operation. + +@see mysqlx_set_group_by() +@ingroup xapi_tbl +*/ + +#define mysqlx_set_select_group_by mysqlx_set_group_by + + +/** + A macro defining a function for setting LIMIT for SELECT operation. + + @see mysqlx_set_limit_and_offset() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_select_limit_and_offset mysqlx_set_limit_and_offset + + +/** + A macro defining a function for setting row locking mode + for SELECT operation. + + @see mysqlx_set_row_locking() + @ingroup xapi_coll +*/ + +#define mysqlx_set_select_row_locking mysqlx_set_row_locking + + +/** + Create a statement executing a table INSERT operation. + + @param table table handle + + @return statement handle for the newly created INSERT operation. + NULL can be returned only in case when there are problems + allocating memory, which normally should not happen. + It is very unlikely for this function to end with an error + because it does not do any parsing, parameter checking etc. + + @note To actually execute the SQL query the returned Statement has to be + given to `mysqlx_execute()` + + @ingroup xapi_tbl +*/ + +PUBLIC_API mysqlx_stmt_t * +mysqlx_table_insert_new(mysqlx_table_t *table); + + +/** + Specify column names for an INSERT statement. + + The function specifies the names of the columns into which the statement + will insert data. User code must ensure that the column values are correct + because the names are not validated until receiving the query on + the server side after executing with `mysqlx_execute()`. + + @param stmt statement handle + @param ... variable parameters list consisting of column names; the list is + terminated by PARAM_END. + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note Each new call clears the list of column for a given statement + if it was set earlier. + @note If column names are not specified for an insert statement, it will + insert data into all columns of the table. + + @ingroup xapi_tbl +*/ + +PUBLIC_API int +mysqlx_set_insert_columns(mysqlx_stmt_t *stmt, ...); + + +/** + Specify a row to be added by an INSERT statement. + + The function provides the row data for an INSERT statement. + User code must ensure that the number of values and their order matches + the list of columns specified for the operation. If column names were not + explicitly specified, the values must match the columns of the table. + + @param stmt statement handle + @param ... variable parameters list consisting of (type, value) pairs + terminated by PARAM_END. The pairs must be listed in the order they + appear in the list of columns + For MYSQLX_TYPE_BYTES the function will expect three parameters + instead of two as for all other types: + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note Each new call provides the row values for the new row, which + can be used for multi-row inserts + + @ingroup xapi_stmt +*/ + +PUBLIC_API int +mysqlx_set_insert_row(mysqlx_stmt_t *stmt, ...); + + +/** + Create a statement executing a table DELETE operation. + + @param table table handle + + @return handle for the newly created DELETE statement. + NULL can be returned only in case when there are problems + allocating memory, which normally should not happen. + It is very unlikely for this function to end with an error + because it does not do any parsing, parameter checking etc. + + @note To actually execute the statement, use `mysqlx_execute()`. + + @see mysqlx_set_delete_where(), mysqlx_set_delete_limit(), + mysqlx_set_delete_order_by() + + @ingroup xapi_tbl +*/ + +PUBLIC_API mysqlx_stmt_t * +mysqlx_table_delete_new(mysqlx_table_t *table); + + +/** + A macro defining a function for setting WHERE clause for DELETE operation. + + @see mysqlx_set_where() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_delete_where mysqlx_set_where + +/** + A macro defining a function for setting LIMIT for DELETE operation. + + @see mysqlx_set_limit_and_offset() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_delete_limit(STMT, LIM) mysqlx_set_limit_and_offset(STMT, LIM, 0) + +/** + A macro defining a function for setting ORDER BY for DELETE operation. + + @see mysqlx_set_order_by() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_delete_order_by mysqlx_set_order_by + + +/** + Create a statement executing a table UPDATE operation. + + @param table table handle + + @return handle for the newly created UPDATE statement. + NULL can be returned only in case when there are problems + allocating memory, which normally should not happen. + It is very unlikely for this function to end with an error + because it does not do any parsing, parameter checking etc. + + @note To actually execute the statement, use `mysqlx_execute()` after + specifying what updates should it perform. + + @see mysqlx_set_update_values(), mysqlx_set_update_where(), + mysqlx_set_update_limit(), mysqlx_set_update_order_by() + + @ingroup xapi_tbl +*/ + +PUBLIC_API mysqlx_stmt_t * +mysqlx_table_update_new(mysqlx_table_t *table); + + +/** + Set values for the columns in the UPDATE statement. + + @param stmt statement handle + @param ... variable parameters list consisting of triplets + + representing column names, value types and values as + expressions. The list is terminated by `PARAM_END`: + column_1, type_1, val_1, ..., column_n, type_n, val_n, `PARAM_END`. + The value type is defined in `mysqlx_data_type_t` enum. + If the value is to be computed on the server side the type + has to be set to `MYSQLX_TYPE_EXPR`. The value (expression) + should be specified as a character string expression. + For `MYSQLX_TYPE_BYTES` the function will expect four parameters + instead of three as for all other types: + + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note The `param` list must be not empty, otherwise error is reported. + + @note All fields and their corresponding expressions must be set in one call + otherwise the next call to this function will reset all parameters to + their new values. + + @ingroup xapi_tbl +*/ + +PUBLIC_API int mysqlx_set_update_values(mysqlx_stmt_t *stmt, ...); + + +/** + A macro defining a function for setting WHERE clause for UPDATE operation. + + @see mysqlx_set_where() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_update_where mysqlx_set_where + + +/** + A macro defining a function for setting LIMIT for UPDATE operation. + + @see mysqlx_set_limit_and_offset() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_update_limit(STMT, LIM) mysqlx_set_limit_and_offset(STMT, LIM, 0) + + +/** + A macro defining a function for setting ORDER BY clause for UPDATE + operation. + + @see mysqlx_set_oder_by() + @ingroup xapi_tbl +*/ + +#define mysqlx_set_update_order_by mysqlx_set_order_by + + +/* + ==================================================================== + Statement execution + ==================================================================== +*/ + +/** + Execute a statement + + Executes statement created by `mysqlx_table_select_new()`, + `mysqlx_table_insert_new()`, `mysqlx_table_update_new()`, + `mysqlx_table_delete_new()`, `mysqlx_sql_new()`, etc. + + @param stmt statement handle + + @return handle that can be used to access results + of the operation. Returned handle is valid until the statement + handle is freed (when session is closed or explicitly with + `mysqlx_free()`) or until another call to `mysqlx_execute()` + on the same statement handle is made. It is also possible to close + a result handle and free all resources used by it earlier with + `mysqlx_free()` call. + On error NULL is returned. The statement is set to an error state and + errors can be examined using the statement handle. + + @ingroup xapi_stmt +*/ + +PUBLIC_API mysqlx_result_t * +mysqlx_execute(mysqlx_stmt_t *stmt); + + +/** + Bind values for parametrized statements. + + This function binds values of either `?` placeholders in an SQL statement + or of named parameters that can be used in other statements. + + User code must ensure that the number of values in bind is the same + as the number of parameters in the query because this is not checked + until receiving the query on the server side. + + @param stmt statement handle + @param ... variable parameters list, which has different structure for SQL + statements that use placeholders and for other statements that use + named parameters. + + For SQL statements it is consisting of (type, value) pairs + terminated by `PARAM_END`: type_id1, value1, type_id2, value2, ..., + type_id_n, value_n, `PARAM_END`. + + For SELECT, INSERT, UPDATE, DELETE, FIND, ADD, MODIFY and REMOVE + statements, the parameters come as triplets (param_name, type, + value): name1, type_id1, value1, name2, type_id2, value2, ..., + name_n, type_id_n, value_n, `PARAM_END` (`PARAM_END` marks the end + of the parameters list). + + type_id is the numeric identifier, which helps to determine the type + of the value provided as the next parameter. The user code must + ensure that type_id corresponds to the actual value type. Otherwise, + the value along with and all sequential types and values are most + likely to be corrupted. + + It is recommended to use `PARAM_TTT()` macros to keep the list + integrity: `PARAM_UINT()`, `PARAM_SINT()`, `PARAM_FLOAT()`, + `PARAM_DOUBLE()`, `PARAM_STRING()`, `PARAM_BYTES()`, `PARAM_EXPR()` + for different data types instead of (`MYSQLX_TYPE_TTT`, value) pairs. + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note Each new call resets the binds set by the previous call to + `mysqlx_stmt_bind()` + + @ingroup xapi_stmt +*/ + +PUBLIC_API int mysqlx_stmt_bind(mysqlx_stmt_t *stmt, ...); + + +/** + Specify a table query projection. + + Using projection, rows found by the query can be mapped to a new set of + rows which is returned in the final result. Projection is given by a list + of expressions determining values of fields in the resulting rows. These + expressions can refer to the fields in the original row (via column names + of the original table). + + @param stmt handle to the statement for which the projection is set + @param ... variable parameters list consisting of character strings + containing expressions: proj_1, ..., proj_n, PARAM_END + (PARAM_END marks the end of projection's item list) + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note This function can be only called for table SELECT statements + @see mysqlx_table_select_new() + + @ingroup xapi_stmt +*/ + +PUBLIC_API int mysqlx_set_items(mysqlx_stmt_t *stmt, ...); + + +/** + Specify selection criteria for a statement. + + Restrict the statement to rows/documents that satisfy + given selection criteria: + - for select/find operations limit the returned rows/documents, + - for update/modify/delete/remove operations limit + the rows/documents affected by the operations. + + Statements supported by this function: SELECT, FIND, UPDATE, MODIFY, DELETE, + REMOVE. Calling it for INSERT or ADD will result in an error + + @param stmt statement handle + @param where_expr character string containing Boolean expression + like in SQL WHERE clause + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note this function can be be used directly, but for the convenience + the code can use the specialized macros for a specific operation. + For SELECT operation the user code should use + `mysqlx_set_select_where()` macros that map the + corresponding `mysqlx_set_where()` function. + This way the unsupported operations will not be used. + + @ingroup xapi_stmt +*/ + +PUBLIC_API int mysqlx_set_where(mysqlx_stmt_t *stmt, const char *where_expr); + + +/** + Specify filter conditions for a group of rows/documents or aggregates + such as GROUP BY + + Restrict the statement to rows/documents that satisfy + given selection criteria: + - for select/find operations limit the returned rows/documents, + + Statements supported by this function: SELECT, FIND. + Calling it for UPDATE, MODIFY, DELETE, REMOVE, INSERT or ADD + will result in an error + + @param stmt statement handle + @param having_expr character string containing Boolean expression + like in SQL HAVING clause + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note this function can be be used directly, but for the convenience + the code can use the specialized macros for a specific operation. + For SELECT operation the user code should use + `mysqlx_set_select_having()` macros that map the + corresponding `mysqlx_set_having()` function. + This way the unsupported operations will not be used. + + @ingroup xapi_stmt +*/ + +PUBLIC_API int mysqlx_set_having(mysqlx_stmt_t *stmt, const char *having_expr); + + +/** + Specify one or more columns/values to group the result in conjunction + with the aggregate functions. + + Statements supported by this function: SELECT, FIND. + Calling it for UPDATE, MODIFY, DELETE, REMOVE, INSERT or ADD + will result in an error + + @param stmt statement handle + @param ... variable parameters list consisting of character strings + containing expressions specifying grouping: + expr_1, ..., expr_n, PARAM_END + (PARAM_END marks the end of projection's item list) + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note this function can be be used directly, but for the convenience + the code can use the specialized macros for a specific operation. + For SELECT operation the user code should use + `mysqlx_set_select_group_by()` macros that map the + corresponding `mysqlx_set_group_by()` function. + This way the unsupported operations will not be used. + + @ingroup xapi_stmt +*/ + +PUBLIC_API int mysqlx_set_group_by(mysqlx_stmt_t *stmt, ...); + +/** + Specify ordering for a statement. + + Operations supported by this function: + SELECT, FIND, UPDATE, MODIFY, DELETE, REMOVE + Calling it for INSERT or ADD will result in an error + + @param stmt statement handle + @param ... variable parameters list consisting of (expression, direction) + pairs terminated by `PARAM_END`: expr_1, direction_1, ..., expr_n, + direction_n, `PARAM_END`. + Each expression computes a value used to sort + the rows/documents in ascending or descending order, + as determined by direction constant + (list the direction enum names). + Special attention must be paid to the expression + strings because the empty string "" or NULL will be treated + as the end of sequence + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note this function can be be used directly, but for the convenience + the code can use the specialized macros for a specific operation. + For SELECT operation the user code should use + `mysqlx_set_select_order_by()` macros that map the + corresponding `mysqlx_set_order_by()` function. + This way the unsupported operations will not be used. + + @ingroup xapi_stmt +*/ + +PUBLIC_API int mysqlx_set_order_by(mysqlx_stmt_t *stmt, ...); + + +/** + Set limit and offset information for a statement. + + Set LIMIT and OFFSET for statement operations which work on ranges of + rows/documents: for select/find operations limit the number of returned + rows/documents, for update/delete limit the number of documents affected + by the operation. + + Operations supported by this function: + SELECT, FIND - use both LIMIT and OFFSET + UPDATE, MODIFY, DELETE, REMOVE - use only LIMIT + + Calling it for INSERT or ADD will result in an error + + @param stmt statement handle + @param row_count the number of result rows to return + @param offset the number of rows to skip before starting counting + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note this function can be be used directly, but for the convenience + the code can use the specialized macros for a specific operation. + For SELECT operation the user code should use + `mysqlx_set_select_limit_and_offset()` macros that map the + corresponding `mysqlx_set_limit_and_offset()` function. + This way the unsupported operations will not be used. + + @note Each call to this function replaces previously set LIMIT + + @ingroup xapi_stmt +*/ + +PUBLIC_API int +mysqlx_set_limit_and_offset(mysqlx_stmt_t *stmt, uint64_t row_count, + uint64_t offset); + +/** + Set row locking mode for a statement. + + Set row locking mode for statement operations working on ranges of + rows/documents. + + Operations supported by this function: + SELECT, FIND + + Calling it for INSERT, UPDATE, DELETE, ADD, MODIFY and REMOVE + will result in an error. + + @param stmt statement handle + @param locking the integer mode identifier (see ::mysqlx_row_locking_t). + @param contention the integer locking contention + (see ::mysqlx_lock_contention_t). + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + + @note this function can be be used directly, but for the convenience + the code can use the specialized macros for a specific operation. + For SELECT operation the user code should use + `mysqlx_set_select_row_locking()` macros that map the + corresponding `mysqlx_set_row_locking()` function. + This way the unsupported operations will not be used. + + @note Each call to this function replaces previously set locking mode + + @ingroup xapi_stmt +*/ +PUBLIC_API int +mysqlx_set_row_locking(mysqlx_stmt_t *stmt, int locking, int contention); + +/** + Free the allocated handle explicitly. + + After calling this function on a handle it becomes invalid and + should not be used any more. + + @note This function should not be called on a client or session handle + - use `mysqlx_client_close()` or `mysqlx_session_close()` instead. + + @note Statement, result, schema, collection, table and some error + handles are also freed automatically when the session is closed. + + @note Only errors that originate from an already established session are + freed automatically when that session is closed. + Errors reported from one of the following functions when they + fail to create a new session or a new client must be freed explicitly: + `mysqlx_get_session()`, `mysqlx_get_session_from_url()`, + `mysqlx_get_session_from_options()`, `mysqlx_get_session_from_client()`, + `mysqlx_get_client_from_url()` and `mysqlx_get_client_from_options()`. + + @param obj object handle + + @ingroup xapi_stmt +*/ + +PUBLIC_API void mysqlx_free(void *obj); + + +/* + ==================================================================== + Result handling + ==================================================================== +*/ + +/** + Fetch one row from the result + + The result is advanced to the next row (if any). + + @param res result handle + + @return row handle or NULL if no more rows left or if an error + occurred. In case of an error it can be retrieved from + the result using `mysqlx_error()` or `mysqlx_error_message()`. + + @note The previously fetched row and its data will become invalid. + + @ingroup xapi_res +*/ + +PUBLIC_API mysqlx_row_t * mysqlx_row_fetch_one(mysqlx_result_t *res); + + +/** + Fetch one document as a JSON string + + @param res result handle + + @param[out] out_length the total number of bytes in the JSON string; + can be NULL, in that case nothing is returned through + this parameter and user must ensure the data is correctly + interpreted + + @return pointer to character JSON string or NULL if no more documents left + in the result. No need to free this data as it is tied and freed + with the result handle. + + @ingroup xapi_res +*/ + +PUBLIC_API const char * mysqlx_json_fetch_one(mysqlx_result_t *res, size_t *out_length); + + +/** + Proceed to the next result set in the reply. + + This function is used to process replies containing multiple result sets. + After a successful call to this function, given result handle will be moved + to access the next result set from the reply. + + @note Any data from the previous result set that has not yet been fetched + is no more accessible after moving to the next result set. + + @param res result handle + + @return `RESULT_OK` - on success; `RESULT_NULL` when there is no more results; + `RESULT_ERROR` - on error + + @ingroup xapi_res +*/ + +PUBLIC_API int mysqlx_next_result(mysqlx_result_t *res); + + +/** + Get number of rows affected by a statement. + + @param res result handle + + @return the number of rows affected by the statement that produced the result + + @note The returned number is meaningful only for results of statements which + modify data stored in a table or collection. + + @ingroup xapi_res +*/ + +PUBLIC_API uint64_t +mysqlx_get_affected_count(mysqlx_result_t *res); + + +/** + Store result data in an internal buffer + + Rows/documents contained in a result must be fetched in a timely fashion. + Failing to do that can result in an error and lost access to the + remaining part of the result. This function can store complete result + in memory so it can be accessed at any time, as long as the result + handle is valid. + + @param result result handle + @param[out] num number of records buffered. Zero is never returned. If the + number of records to buffer is zero the function returns + `RESULT_ERROR` + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error. If the error + occurred it can be retrieved by `mysqlx_error()` function. + + @note Even in case of an error some rows/documents might be buffered if they + were retrieved before the error occurred. + @note When called for second time on the same result the function + does not store anything because the data is already buffered. + Instead it returns the number of items that have not been + fetched yet. + + @ingroup xapi_res +*/ + +PUBLIC_API int +mysqlx_store_result(mysqlx_result_t *result, size_t *num); + + +/** + Function for getting the number of remaining cached items in a result. + If nothing is cached if will attempt to store result in the internal + cache like `mysqlx_store_result()`. + + @param result result handle + @param[out] num number of records buffered. + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error. If the error + occurred it can be retrieved by `mysqlx_error()` function. + + @note Even in case of an error some rows/documents might be buffered if they + were retrieved before the error occurred. + + @ingroup xapi_res +*/ + +PUBLIC_API int +mysqlx_get_count(mysqlx_result_t *result, size_t *num); + + +/** + Get identifiers of the documents added to the collection. + + This function returns both generated document ids and document ids specified + by user in `_id` field. + + The function can be used for the multi-document inserts. In this case each + call to `mysqlx_fetch_generated_id()` returns identifier of the next document, + until NULL is returned. + + @param result handle to a result of a statement which adds documents to + a collection + + @return character string containing an identifier of a document added by the + statement; NULL - if all UUIDs for all added documents have been + returned + + @note The returned string is valid as long as the result handle is valid. + Starting a new operation will invalidate it. + + @ingroup xapi_res +*/ + +PUBLIC_API const char * +mysqlx_fetch_generated_id(mysqlx_result_t *result); + + +/** + Get auto increment value generated by a statement that inserts rows + into a table with auto increment column. + + @param res handle to a result of INSERT statement + + @return the generated auto increment value + + @note with multi-row inserts the function returns the value generated + for the first row + + @ingroup xapi_res +*/ + +PUBLIC_API uint64_t +mysqlx_get_auto_increment_value(mysqlx_result_t *res); + + +/** + Read bytes stored in a row into a pre-allocated buffer + + The raw bytes are as received from the server. In genral the value + is represented using x-protocol encoding that corresponds to the + type and other meta-data of the given column. This information can + be obtained from `mysqlx_column_get_type()` and other + `mysqlx_column_get_*()` functions. + + The x-protocol represenation of different value types is documented + [here] + (https://dev.mysql.com/doc/dev/mysql-server/latest/structMysqlx_1_1Resultset_1_1ColumnMetaData.html). + Most types in the #mysqlx_data_type_t enumeration correspond + to an x-protocol value type of the same name. + + STRING values are encoded using the character set encoding as reported by + mysqlx_column_get_collation() function. + + JSON data is represented as a JSON string. ENUM values are represented + as strings with enum constant names. Values of type TIMESTAMP use + the same representation as DATETIME. GEOMETRY values use the internal + geometry storage format described + [here] + (https://dev.mysql.com/doc/refman/8.0/en/gis-data-formats.html). + + Types BOOL and EXPR are never reported for data received from server + -- they are used when sending data to the server. + + Note that raw representation of BYTES and STRING values has an extra + 0x00 byte added at the end, which is not part of the originial data. + It is used to distinguish null values from empty byte sequences. + + @param row row handle + @param col zero-based column number + @param offset the number of bytes to skip before reading them from source row + @param[out] buf the buffer allocated on the user side into which to write data + @param[in,out] buf_len pointer to a variable holding the length of the buffer + [IN], the number of bytes actually written into the + buffer [OUT] + + @return `RESULT_OK` - on success; `RESULT_NULL` when the value in the + requested column is NULL; `RESULT_MORE_DATA` if not all data was + fetched after the last call to the function; + `RESULT_ERROR` - on error + + @ingroup xapi_res +*/ + +PUBLIC_API int +mysqlx_get_bytes(mysqlx_row_t* row, uint32_t col, + uint64_t offset, void *buf, size_t *buf_len); + + +/** + Get an unsigned integer number from a row. + + It is important to pay attention to the signed/unsigned type of the column. + Attempting to call this function for a column whose type is different from + `MYSQLX_TYPE_UINT` will result in wrong data being retrieved. + + @param row row handle + @param col zero-based column number + @param[out] val the pointer to a variable of the 64-bit unsigned integer + type in which to write the data + + @return `RESULT_OK` - on success; `RESULT_NULL` when the column is NULL; + `RESULT_ERROR` - on error + + @ingroup xapi_res +*/ + +PUBLIC_API int +mysqlx_get_uint(mysqlx_row_t* row, uint32_t col, uint64_t* val); + + +/** + Get a signed integer number from a row. + + It is important to pay attention to the signed/unsigned type of the column. + Attempting to call this function for a column whose type is different from + `MYSQLX_TYPE_SINT` will result in wrong data being retrieved. + + @param row row handle + @param col zero-based column number + @param[out] val the pointer to a variable of the 64-bit signed integer + type in which to write the data + + @return `RESULT_OK` - on success; `RESULT_NULL` when the column is NULL; + `RESULT_ERROR` - on error + + @ingroup xapi_res +*/ + +PUBLIC_API int +mysqlx_get_sint(mysqlx_row_t* row, uint32_t col, int64_t* val); + + +/** + Get a float number from a row. + + It is important to pay attention to the type of the column. + Attempting to call this function for a column whose type is different from + `MYSQLX_TYPE_FLOAT` will result in wrong data being retrieved. + + @param row row handle + @param col zero-based column number + @param[out] val the pointer to a variable of the float + type in which to write the data + + @return `RESULT_OK` - on success; `RESULT_NULL` when the column is NULL; + `RESULT_ERROR` - on error + + @ingroup xapi_res +*/ + +PUBLIC_API int +mysqlx_get_float(mysqlx_row_t* row, uint32_t col, float* val); + + +/** + Get a double number from a row. + + It is important to pay attention to the type of the column. + Attempting to call this function for a column whose type is different from + `MYSQLX_TYPE_DOUBLE` will result in wrong data being retrieved. + + @param row row handle + @param col zero-based column number + @param[out] val the pointer to a variable of the double + type in which to write the data. + + @return `RESULT_OK` - on success; `RESULT_NULL` when the column is NULL; + `RESULT_ERROR` - on error + + @ingroup xapi_res +*/ + +PUBLIC_API int +mysqlx_get_double(mysqlx_row_t* row, uint32_t col, double *val); + + +/** + Free the result explicitly. + + @note This function is DEPRECATED. Use `mysqlx_free()` instead. + + @note Results are also freed automatically when the corresponding + statement handle is freed. + + @param res the result handle + + @ingroup xapi_res +*/ + +PUBLIC_API void mysqlx_result_free(mysqlx_result_t *res); + + +/* + Result metadata + --------------- +*/ + +/** + Get column type identifier. + + @param res result handle + @param pos zero-based column number + + @return column type identifier (see `mysqlx_data_type_t` enum) + + @ingroup xapi_md +*/ + +PUBLIC_API uint16_t +mysqlx_column_get_type(mysqlx_result_t *res, uint32_t pos); + + +/** + Get column collation number. + + @param res result handle + @param pos zero-based column number + + @return column collation number. The number matches the ID + in the INFORMATION_SCHEMA.COLLATIONS table. + @see https://dev.mysql.com/doc/mysql/en/collations-table.html + + @ingroup xapi_md +*/ + +PUBLIC_API uint16_t +mysqlx_column_get_collation(mysqlx_result_t *res, uint32_t pos); + + +/** + Get column length. + + @param res result handle + @param pos zero-based column number + + @return maximum length of data in the column in bytes + as reported by server. + + @note because the column length is returned as byte length + it could be confusing with the multi-byte charsets. + For instance with UTF8MB4 the length of VARCHAR(100) + column is returned as 400 because each character is + 4 bytes long. + + @ingroup xapi_md +*/ + +PUBLIC_API uint32_t +mysqlx_column_get_length(mysqlx_result_t *res, uint32_t pos); + + +/** + Get column precision. + + @param res result handle + @param pos zero-based column number + + @return number of digits after the decimal point + + @ingroup xapi_md +*/ + +PUBLIC_API uint16_t +mysqlx_column_get_precision(mysqlx_result_t *res, uint32_t pos); + + +/* + Get column flags. + + @param res result handle + @param pos zero-based column number + + @return 32-bit unsigned integer containing column flags reported by + server. TODO: Document these + + @ingroup xapi_md +*/ +//PUBLIC_API uint32_t +//mysqlx_column_get_flags(mysqlx_result_t *res, uint32_t pos); + + +/** + Get the number of columns in the result. + + @param res result handle + + @return the number of columns in the result + + @note If the result does not contain rows, 0 columns are reported. + @note For a result with multiple result sets, the number of columns for + the current result set is reported (see `mysqlx_next_result()`). + + @ingroup xapi_md +*/ + +PUBLIC_API uint32_t +mysqlx_column_get_count(mysqlx_result_t *res); + + +/** + Get column name. + + @param res result handle + @param pos zero-based column number + + @return character string containing the column name + + @ingroup xapi_md +*/ + +PUBLIC_API const char * +mysqlx_column_get_name(mysqlx_result_t *res, uint32_t pos); + + +/** + Get column original name. + + @param res result handle + @param pos zero-based column number + + @return character string containing the column original name + + @ingroup xapi_md +*/ + +PUBLIC_API const char * +mysqlx_column_get_original_name(mysqlx_result_t *res, uint32_t pos); + + +/** + Get column's table name. + + @param res result handle + @param pos zero-based column number + + @return character string containing the column table name + + @ingroup xapi_md +*/ + +PUBLIC_API const char * +mysqlx_column_get_table(mysqlx_result_t *res, uint32_t pos); + + +/** + Get column's original table name. + + @param res result handle + @param pos zero-based column number + + @return character string containing the column original table + + @ingroup xapi_md +*/ + +PUBLIC_API const char * +mysqlx_column_get_original_table(mysqlx_result_t *res, uint32_t pos); + + +/** + Get column's schema name. + + @param res result handle + @param pos zero-based column number + + @return character string containing the column schema + + @ingroup xapi_md +*/ + +PUBLIC_API const char * +mysqlx_column_get_schema(mysqlx_result_t *res, uint32_t pos); + + +/** + Get column's catalog name. + + @param res result handle + @param pos zero-based column number + + @return character string containing the column name + + @ingroup xapi_md +*/ + +PUBLIC_API const char * +mysqlx_column_get_catalog(mysqlx_result_t *res, uint32_t pos); + + +/* + ==================================================================== + DDL statements + ==================================================================== +*/ + +/** + Create a schema + + @param sess session handle + @param schema the name of the schema to be created + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + The error handle can be obtained from the session + using `mysqlx_error()` function. + + @ingroup xapi_ddl +*/ + +PUBLIC_API int +mysqlx_schema_create(mysqlx_session_t *sess, const char *schema); + + +/** + Drop a schema + + @param sess session handle + @param schema the name of the schema to be dropped + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + The error handle can be obtained from the session + using `mysqlx_error()` function. + + @ingroup xapi_ddl +*/ + +PUBLIC_API int +mysqlx_schema_drop(mysqlx_session_t *sess, const char *schema); + + +/** + Create a new collection in a specified schema + + @param schema schema handle + @param collection collection name to create + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + The error handle can be obtained from the session + using `mysqlx_error()` function. + + @ingroup xapi_ddl +*/ + +PUBLIC_API int +mysqlx_collection_create(mysqlx_schema_t *schema, const char *collection); + + +/** + Allocate a new create/modify collection options data. + + @return collection create/modify options handle + + @note The session returned by the function must be properly freed using + `mysqlx_free()`. + + @ingroup xapi_ddl +*/ + +PUBLIC_API mysqlx_collection_options_t * +mysqlx_collection_options_new(); + + +/** + Set collection options. + @param options handle created by mysqlx_collection_options_new() function + @param ... variable parameters list consisting of (option, value) pairs + terminated by `PARAM_END`. + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + The error handle can be obtained from the options + using `mysqlx_error()` function. + + The variable parameter list is of the form + + OPT_COLLECTION_O1(val1), OPT_COLLECTION_O2(val2), ..., PARAM_END + + or, equivalently, + + MYSQLX_OPT_COLLECTION_O1, val1, MYSQLX_OPT_COLLECTION_02, val2,..., + PARAM_END + + Possible options are defined by enumerations + \ref opt_collection "mysqlx_collection_opt_t" and + \ref opt_collection_validation "mysqlx_collection_validation_opt_t". + Type of option value `vali` (number, string, etc.) must match the option + `MYSQLX_OPT_COLLECTION_Oi`, otherwise this value along with all the + sequential options and values are most likely to be corrupted. + + @ingroup xapi_ddl +*/ + +PUBLIC_API int +mysqlx_collection_options_set(mysqlx_collection_options_t * options,...); + + +/** + Create a new collection in a specified schema + + @param schema schema handle + @param collection collection name to create + @param options handle created by mysqlx_collection_options_new() function + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + The error handle can be obtained from the session + using `mysqlx_error()` function. + + @ingroup xapi_ddl +*/ + +PUBLIC_API int +mysqlx_collection_create_with_options(mysqlx_schema_t *schema, + const char *collection, + mysqlx_collection_options_t *options); + +/** + Create a new collection in a specified schema + + @param schema schema handle + @param collection collection name to create + @param json_options json with options: + ~~~~~~ + { + "reuseExisting": true, + "validation": + { + "level": "Strict", + "schema": + { + "id": "http://json-schema.org/geo", + "$schema": "http://json-schema.org/draft-06/schema#", + "description": "A geographical coordinate", + "type": "object", + "properties": + { + "latitude": + { + "type": "number" + }, + "longitude": + { + "type": "number" + } + }, + "required": ["latitude", "longitude"] + } + } + } + } + ~~~~~~ + + Document keys: + - `reuseExisting` : Same as @ref opt_collection "MYSQLX_OPT_COLLECTION_REUSE"; + - `validation` : Same as @ref opt_collection "MYSQLX_OPT_COLLECTION_VALIDATION"; + + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + The error handle can be obtained from the session + using `mysqlx_error()` function. + + @ingroup xapi_ddl +*/ +PUBLIC_API int +mysqlx_collection_create_with_json_options(mysqlx_schema_t *schema, + const char *collection, + const char* json_options); + +PUBLIC_API int +mysqlx_collection_modify_with_options(mysqlx_schema_t *schema, + const char *collection, + mysqlx_collection_options_t *options); + +PUBLIC_API int +mysqlx_collection_modify_with_json_options(mysqlx_schema_t *schema, + const char* collection, + const char* json_options); + + + +/** + Drop an existing collection in a specified schema + + @param schema schema handle + @param collection collection name to drop + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + The error handle can be obtained from the session + using `mysqlx_error()` function + + @ingroup xapi_ddl +*/ + +PUBLIC_API int +mysqlx_collection_drop(mysqlx_schema_t *schema, const char *collection); + + +/* + ==================================================================== + Diagnostics + ==================================================================== +*/ + + +/** + Get the last error from the object. + + @param obj handle to the object to extract the error information from. + Supported handle types are `mysqlx_session_t`, + `mysqlx_session_options_t`, `mysqlx_schema_t`, + `mysqlx_collection_t`, `mysqlx_table_t`, `mysqlx_stmt_t`, + `mysqlx_result_t`, `mysqlx_row_t`, `mysqlx_error_t` + + @return the error handle or NULL if there is no errors. + + @ingroup xapi_diag +*/ + +PUBLIC_API mysqlx_error_t * mysqlx_error(void *obj); + + +/** + Get the error message from the object. + + @param obj handle to the object to extract the error information from. + Supported handle types are `mysqlx_session_t`, + `mysqlx_session_options_t`, `mysqlx_schema_t`, + `mysqlx_collection_t`, `mysqlx_table_t`, `mysqlx_stmt_t`, + `mysqlx_result_t`, `mysqlx_row_t`, `mysqlx_error_t` + + @return the character string or NULL if there is no errors. + + @ingroup xapi_diag +*/ + +PUBLIC_API const char * mysqlx_error_message(void *obj); + + +/** + Get the error number from the object. + + @param obj handle to the object to extract the error information from. + Supported handle types are `mysqlx_session_t`, + `mysqlx_session_options_t`, `mysqlx_schema_t`, + `mysqlx_collection_t`, `mysqlx_table_t`, `mysqlx_stmt_t`, + `mysqlx_result_t`, `mysqlx_row_t`, `mysqlx_error_t` + + @return the error number or 0 if no error + + @ingroup xapi_diag +*/ + +PUBLIC_API unsigned int mysqlx_error_num(void *obj); + + +/** + Get the number of warnings generated by a statement. + + @param res result handle + + @return the number of warnings stored in the result + @ingroup xapi_diag +*/ + +PUBLIC_API unsigned int mysqlx_result_warning_count(mysqlx_result_t *res); + + +/** + Get the next warning from the result. + + This function returns a handle to a warning which can be examined using + the same functions used for errors: `mysqlx_error_num()` and + `mysqlx_error_message()`. + + @param res result handle + + @return handle to the next warning from the result or + NULL if there is no more warnings left to return. + + @note The warning handle returned by a previous call is invalidated. + + @ingroup xapi_diag +*/ + +PUBLIC_API mysqlx_error_t * +mysqlx_result_next_warning(mysqlx_result_t *res); + + +/** + Create index for a collection. + + This function creates a named index in the collection using a JSON index + specification. + + @param coll collection to create the index for + @param name name for the index to be created + @param idx_spec index specification as a JSON string + + @see @ref indexing for information on how to define document + collection indexes. + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + The error handle can be obtained from the collection + using `mysqlx_error()` function. + + @ingroup xapi_ddl +*/ + +PUBLIC_API int +mysqlx_collection_create_index(mysqlx_collection_t *coll, const char *name, + const char *idx_spec); + +/** + Drop index on a collection + + This function drops an index in a collection + with a specific name + + @param coll collection whose index should be dropped + @param name name of the index to be dropped + + @return `RESULT_OK` - on success; `RESULT_ERROR` - on error + The error handle can be obtained from the collection + using `mysqlx_error()` function. + + @note The warning handle returned by a previous call is invalidated. + + @ingroup xapi_ddl +*/ + +PUBLIC_API int +mysqlx_collection_drop_index(mysqlx_collection_t *coll, const char *name); + + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif /* __MYSQLX_H__*/ diff --git a/Libraries/mysql-connector/include/mysqlx/xdevapi.h b/Libraries/mysql-connector/include/mysqlx/xdevapi.h new file mode 100644 index 0000000..69586c8 --- /dev/null +++ b/Libraries/mysql-connector/include/mysqlx/xdevapi.h @@ -0,0 +1,2141 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, as + * published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * Without limiting anything contained in the foregoing, this file, + * which is part of Connector/C++, is also subject to the + * Universal FOSS Exception, version 1.0, a copy of which can be found at + * https://oss.oracle.com/licenses/universal-foss-exception. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MYSQL_DEVAPI_H +#define MYSQL_DEVAPI_H + +#ifndef __cplusplus +#error This header can be only used with C++ code +#endif + +/** + @defgroup devapi X DevAPI Classes + + X DevAPI Classes and types. See @ref devapi_example for introduction. + + @defgroup devapi_op Database operations + @ingroup devapi + + Classes representing yet-to-be-executed database operations. + + Such operations are created by various methods of + @link mysqlx::abi2::r0::Collection `Collection`@endlink or + @link mysqlx::abi2::r0::Table `Table`@endlink classes. Database operation + classes define methods that specify additional operation characteristics + before it gets executed with `execute()` method. The latter + returns a @link mysqlx::abi2::r0::Result `Result`@endlink, + @link mysqlx::abi2::r0::DocResult `DocResult`@endlink or + @link mysqlx::abi2::r0::RowResult `RowResult`@endlink object, + depending on the type of the operation. + + @defgroup devapi_res Classes for result processing + @ingroup devapi + + Classes used to examine results of a statement and documents or + rows contained in a result. + + @defgroup devapi_aux Auxiliary types + @ingroup devapi +*/ + + +/** + @file + The main header for MySQL Connector/C++ DevAPI. + + This header should be included by C++ code which uses the DevAPI implemented + by MySQL Connector/C++. + + @sa result.h, document.h + + @ingroup devapi +*/ + +/* + X DevAPI public classes are declared in this and other headers included from + devapi/ folder. The main public API classes, such as Session below, contain + declarations of public interface methods. Any obscure details of the public + API, which must be defined in the public header, are factored out + to Session_detail class from which the main Session class inherits. + Among other things, Session_detail declares the implementation class for + Session. This implementation class is opaque and its details are not defined + in the public headers - only in the implementation part. Definitions of + XXX_detail classes can be found in devapi/detail/ sub-folder. +*/ + +#include "devapi/common.h" +#include "devapi/result.h" +#include "devapi/collection_crud.h" +#include "devapi/table_crud.h" +#include "devapi/settings.h" +#include "devapi/detail/session.h" + +namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) + +class Session; + +namespace internal { + +template class Sch_object; + +} // internal + + +/// Collection create/modify Validation options + +class CollectionOptions; + +/** + The CollectionValidation class defines collection schema and level of + validation. + */ + +class CollectionValidation +{ +public: + +#define COLLECTION_VALIDATION_ENUM(x,y) x=y, + + + /** + Collection validation level options + + \anchor CollectionValidation_Level + */ + + enum Level + { + COLLECTION_VALIDATION_LEVEL(COLLECTION_VALIDATION_ENUM) + }; + + + /** + \anchor CollectionValidation_Option + Collection validation options + */ + + enum Option + { + COLLECTION_VALIDATION_OPTION(COLLECTION_VALIDATION_ENUM) + LAST + }; + +private: + + struct Data + { + std::string validation_level; + DbDoc validation_schema; + std::bitset used; + }; + +public: + + CollectionValidation() + {} + + CollectionValidation(const char* json_doc) + : CollectionValidation(DbDoc(json_doc)) + {} + + /** + Constructor using a document. + + Document example: + ~~~~~~ + { + "level": "Strict", + "schema": + { + "id": "http://json-schema.org/geo", + "$schema": "http://json-schema.org/draft-06/schema#", + "description": "A geographical coordinate", + "type": "object", + "properties": + { + "latitude": + { + "type": "number" + }, + "longitude": + { + "type": "number" + } + }, + "required": ["latitude", "longitude"] + } + } + } + ~~~~~~ + + Document keys: + - `level`: See CollectionValidation::LEVEL; + - `schema`: See CollectionValidation::SCHEMA; + + */ + + CollectionValidation(DbDoc doc) + { + for(auto el : doc) + { + if(el == "level") + { + try { + _set(LEVEL, doc[el].get()); + } catch (const Error& e) + { + std::string err("Unexpected level type: "); + err+=e.what(); + throw Error(err.c_str()); + } + } + else if(el == "schema") + { + _set(SCHEMA,doc[el].get()); + } + else { + std::string err("Unexpected schema validation field "); + err+=el; + throw Error(err.c_str()); + } + } + } + + /** + Construct CollectionValidation from list of Option and value pairs. + See @ref CollectionValidation_Option "CollectionValidation::Option" + for possible options. + */ + template + CollectionValidation(Option opt, Rest&&... rest) + { + set(opt, std::forward(rest)...); + } + + /** + Set list of Option and value pairs. + @see CollectionValidation::CollectionValidation + */ + template + void set(Rest&&... options) + { + Data tmp_data(m_data); + try { + _set(std::forward(options)...); + } catch (...) { + m_data = tmp_data; + throw; + } + } + +protected: + + /// @cond DISABLED + // Note: Doxygen gets confused here and renders docs incorrectly. + template + void _set(Option opt, T&& v, Rest&&... options) + { +#define SCHEMA_VALIDATION_SET(x,y) case CollectionValidation::x:\ + do_set(std::forward(v)); break; + + switch (opt) + { + COLLECTION_VALIDATION_OPTION(SCHEMA_VALIDATION_SET) + case CollectionValidation::LAST: throw_error("Invalid option."); ; break; + } + + _set(std::forward(options)...); + } + /// @endcond + + void _set() {} + + template + void do_set(T) + { + throw_error("Invalid option value type."); + } + + Data m_data; + + /// \cond Exclude from doxygen. + friend CollectionOptions; + friend Schema; + friend mysqlx::internal::Schema_detail; + /// \endcond +}; + + +/** + The CollectionOptions class defines collection create/modify options. + */ + +class CollectionOptions +{ + public: + +#define COLLECTION_OPTIONS_ENUM(x,y) x=y, + + /** + \anchor CollectionOptions_Option + Collection options + */ + + enum Option + { + COLLECTION_OPTIONS_OPTION(COLLECTION_OPTIONS_ENUM) + LAST + }; + +private: + + struct Data{ + CollectionValidation validation; + std::bitset used; + bool reuse = false; + }; + + public: + + + CollectionOptions() + {} + + CollectionOptions(const char* options) + : CollectionOptions(DbDoc(options)) + {} + + CollectionOptions(const std::string& options) + : CollectionOptions(DbDoc(options)) + {} + + /** + Constructor using a document. + + Document example: + ~~~~~~ + { + "reuseExisting": true, + "validation": + { + "level": "Strict", + "schema": + { + "id": "http://json-schema.org/geo", + "$schema": "http://json-schema.org/draft-06/schema#", + "description": "A geographical coordinate", + "type": "object", + "properties": + { + "latitude": + { + "type": "number" + }, + "longitude": + { + "type": "number" + } + }, + "required": ["latitude", "longitude"] + } + } + } + } + ~~~~~~ + + Document keys: + - `reuseExisting` : Same as CollectionOptions::REUSE; + - `validation` : Same as CollectionOptions::VALIDATION; + + + */ + CollectionOptions(DbDoc options) + { + for(auto el : options) + { + if(el == "reuseExisting") + { + try { + _set(REUSE, options["reuseExisting"].get()); + } catch (const Error& e) + { + std::string err("Wrong value for reuseExisting option: "); + err+=e.what(); + throw Error(err.c_str()); + } + } + else if(el == "validation") + { + _set(VALIDATION, CollectionValidation(options["validation"].get())); + } + else { + std::string err("Unexpected collection option "); + err+=el; + throw Error(err.c_str()); + } + } + } + + CollectionOptions(CollectionValidation validation) + { + set(VALIDATION, validation); + } + + /** + Construct CollectionOptions from list of Option and value pairs. + @ref CollectionOptions_Option "CollectionOptions::Option" and + @ref CollectionValidation_Option "CollectionValidation::Option" can both be + used. + + Example: + ~~~~ + schema.createCollection( + "collection_test", + CollectionValidation::LEVEL, CollectionValidation::STRICT, + CollectionOptions::REUSE, true, + CollectionValidation::SCHEMA, + R"( + { + "id": "http://json-schema.org/geo", + "$schema": "http://json-schema.org/draft-06/schema#", + "description": "A geographical coordinate", + "type": "object", + "properties": + { + "latitude": { + "type": "number" + }, + "longitude": { + "type": "number" + } + }, + "required": ["latitude", "longitude"] + })" + ); + + ~~~~ + + */ + + template + CollectionOptions(Option opt, Rest&&... rest) + { + set(opt, std::forward(rest)...); + } + + + template + CollectionOptions(CollectionValidation::Option opt, Rest&&... rest) + { + set(opt, std::forward(rest)...); + } + + + /** + Set list of option and value pairs. + @see CollectionOptions::CollectionOptions + */ + template + void set(Rest&&... rest) + { + Data tmp_data(m_data); + try { + _set(std::forward(rest)...); + } catch (...) { + m_data = std::move(tmp_data); + throw; + } + } + + + +protected: + + /// @cond DISABLED + // Note: Doxygen gets confused here and renders docs incorrectly. + template + void _set(Option opt, T&& v, Rest&&... rest) + { +#define COLLECTION_OPTIONS_SET(x,y) case x:\ + do_set(std::forward(v)); break; + + switch (opt) + { + COLLECTION_OPTIONS_OPTION(COLLECTION_OPTIONS_SET) + case LAST: throw_error("Invalid option."); ; break; + } + + _set(std::forward(rest)...); + } + /// @endcond + + template + void _set(CollectionValidation::Option opt, T&& v, Rest&&... rest) + { + m_data.validation._set(opt, std::forward(v)); + _set(std::forward(rest)...); + } + + void _set(){} + + template + void do_set(T) + { + throw_error("Invalid option value type."); + } + + Data m_data; + + /// \cond Exclude from doxygne + friend mysqlx::internal::Schema_detail; + /// \endcond +}; + + +/** + Represents a database schema. + + A `Schema` instance can be obtained from `Session::getSchema()` + method: + + ~~~~~~ + Session session; + Schema mySchema; + + mySchema= session.getSchema("My Schema"); + ~~~~~~ + + or it can be directly constructed as follows: + + ~~~~~~ + Session session; + Schema mySchema(session, "My Schema"); + ~~~~~~ + + Each `Schema` instance is tied to a particular session and all + the operations on the schema and its objects are performed using + that session. If the session is destroyed, an attempt to use a schema of + that session yields an error. + + When creating a `Schema` object, by default no checks are made that + it actually exists in the database. An operation that is executed + on the server and involves such a non-existent schema throws + an error. + + @note A `Schema` object should be used by at most one thread at a time. It is + not safe to call its methods by several threads simultaneously. It is + responsibility of the user to ensure this using a synchronization mechanism + such as mutexes. + + @ingroup devapi +*/ + +class Schema + : protected internal::Schema_detail +{ + Session *m_sess; + +public: + + /** + Construct an object representing the named schema. + */ + + Schema(Session &sess, const string &name); + + /** + Construct an object representing the default schema of the session. + + The default schema is the one specified by session creation options. + */ + + Schema(Session&); + + + /** + Get schema name + */ + + const string& getName() const + { + return m_name; + } + + /** + Get Session object + */ + + Session& getSession() + { + return *m_sess; + } + + const Session& getSession() const + { + return const_cast(this)->getSession(); + } + + /** + Check if this schema exists in the database. + + @note Involves communication with the server. + */ + + bool existsInDatabase() const + { + try { + /* + Note: We get from server a list of schemata filtered by the name of + this schema - if the schema exists the list should not be empty. + */ + internal::Session_detail::Name_src list(*m_sess, m_name); + list.iterator_start(); + return list.iterator_next(); + } + CATCH_AND_WRAP + } + + + /** + Create a new collection in the schema. + + Returns the created collection. Set `reuse` flag to true to return + an already existing collection with the same name. Otherwise, an attempt + to create a collection which already exists throws an error. + */ + + + Collection createCollection(const string &name); + Collection createCollection(const string &name, bool); + + /** + Create a new collection in the schema, optionally specifying creation + options. Arguments following `name`, if any, are used to construct + CollectionOptions object. See CollectionOptions for possible ways of + specifying the options. + + Returns the created collection. + */ + template + Collection createCollection(const string &name, + Rest&&... rest); + + /** + Modify a collection in the schema specifying modify options. Arguments + following `name` are used to construct CollectionOptions object. See + CollectionOptions for possible ways of specifying the options. + + @note CollectionOptions::REUSE is not allowed and, if used, will throw + error. + */ + template + void modifyCollection(const string &name, Rest&&... options); + + + /** + Return an object representing a collection with the given name. + + To check if the collection actually exists in the database set + `check_existence` flag to true. Otherwise the returned object can refer to + a non-existing collection. An attempt to use such a non-existing collection + in a database operation throws an error. + + @note Checking the existence of a collection involves communication with + the server. If `check_exists` is false, on the other hand, no I/O is + involved when creating a `Collection` object. + */ + + Collection getCollection(const string &name, bool check_exists = false); + + /** + Return an object representing a table or a view with the given name. + + To check if the table actually exists in the database set + `check_existence` flag to true. Otherwise the returned object can refer to + a non-existing table. An attempt to use such a non-existing table + in a database operation throws an error. + + @note The returned `Table` object can represent a plain table or + a view. See `Table` class description. + + @note Checking the existence of a table involves communication with + the server. If `check_exists` is false, on the other hand, no I/O is + involved when creating a `Table` object. + */ + + Table getTable(const string &name, bool check_exists = false); + + /** + Get a list of all collections in the schema. + + The returned value can be stored in a container that holds `Collection` + objects, such as `std::vector`. + */ + + CollectionList getCollections() + { + try { + return Collection_src(*this, "%"); + } + CATCH_AND_WRAP + } + + /** + Get a list of names of all collections in the schema. + + The returned value can be stored in a container that holds strings, such as + `std::vector`. + */ + + StringList getCollectionNames() + { + try { + return Name_src(*this, COLLECTION, "%"); + } + CATCH_AND_WRAP + } + + /** + Get a list of all tables and views in the schema. + + The returned value can be stored in a container that holds `Table` + objects, such as `std::vector`. + + @note The list also contains views which are represented by `Table` objects + - see `Table` class description. + */ + + TableList getTables() + { + try { + return Table_src(*this, "%"); + } + CATCH_AND_WRAP + } + + /** + Get a list of names of all tables and views in the schema. + + The returned value can be stored in a container that holds strings, such as + `std::vector`. + + @note The list also contains names of views as views are represented + by `Table` objects - see `Table` class description. + */ + + StringList getTableNames() + { + try { + return Name_src(*this, TABLE, "%"); + } + CATCH_AND_WRAP + } + + /** + Return a table corresponding to the given collection. + + The table has two columns: `_id` and `doc`. For each document in + the collection there is one row in the table with `doc` filed holding + the document as a JSON value and `_id` field holding document's identifier. + + To check if the collection actually exists in the database set + `check_existence` flag to true. Otherwise the returned table can refer to + a non-existing collection. An attempt to use such a non-existing collection + table throws an error. + + @note Checking the existence of a collection involves communication with + the server. If `check_exists` is false, on the other hand, no I/O is + involved when creating the `Table` object. + */ + + Table getCollectionAsTable(const string &name, bool check_exists = true); + + + /** + Drop the given collection from the schema. + + This method silently succeeds if a collection with the given name does + not exist. + + @note If a table name is passed to the method, it behaves like + dropTable(). + */ + + void dropCollection(const mysqlx::string& name) + { + try { + Schema_detail::drop_collection(name); + } + CATCH_AND_WRAP + } + + + friend Collection; + friend Table; + + ///@cond IGNORE + friend internal::Schema_detail::Name_src; + template friend class internal::Sch_object; + ///@endcond +}; + + +/* + Database objects that belong to some schema + =========================================== +*/ + + +namespace internal { + +// Common base for schema objects defining the common API methods. + +template +class Sch_object + : public Base +{ +protected: + + Schema m_schema; + + Sch_object(const Schema &sch, const string &name); + +public: + + using string = mysqlx::string; + + /** + Get database object name + */ + + const string& getName() const + { + return Base::m_name; + } + + /** + Get Session object + */ + + Session& getSession() + { + return m_schema.getSession(); + } + + /** + Get schema object + */ + + const Schema& getSchema() const + { + return m_schema; + } + +protected: + + std::shared_ptr get_session(); + + Schema_detail& get_schema() + { + return m_schema; + } +}; + +} // internal + + + + + + + +/** + Represents a collection of documents in a schema. + + A collection object can be obtained from `Schema::getCollection()` + method: + + ~~~~~~ + Schema db; + Collection myColl; + + myColl= db.getCollection("My Collection"); + ~~~~~~ + + or directly constructed as follows: + + ~~~~~~ + Schema db; + Collection myColl(db, "My Collection"); + ~~~~~~ + + When creating a `Collection` object, by default no checks are made that + it actually exists in the database. An operation that is executed + on the server and involves such a non-existent collection throws + an error. Call `existsInDatabase()` to check the existence of the collection. + + @note A `Collection` object should be used by at most one thread at a time. + It is not safe to call its methods by several threads simultaneously. It is + responsibility of the user to ensure this using a synchronization mechanism + such as mutexes. + + @ingroup devapi +*/ + +class Collection + : protected internal::Sch_object +{ +public: + + Collection(const Schema &sch, const string &name) + try + : Sch_object(sch, name) + {} + CATCH_AND_WRAP + + + using Sch_object::getName; + using Sch_object::getSession; + using Sch_object::getSchema; + + bool existsInDatabase() const + { + try { + Schema::StringList list(m_schema, Schema::COLLECTION, m_name); + return list.begin() != list.end(); + } + CATCH_AND_WRAP + } + + /** + Get the number of documents in the collection. + */ + + uint64_t count(); + + /* + CRUD operations on a collection + ------------------------------- + */ + + /** + Return an operation which fetches all documents from the collection. + + Call `execute()` on the returned operation object to execute it and get + a `DocResult` object that gives access to the documents. Specify additional + query parameters, such as ordering of the documents, using chained methods + of `CollectionFind` class before making the final call to `execute()`. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `CollectionFind` + */ + + CollectionFind find() + { + try { + return CollectionFind(*this); + } + CATCH_AND_WRAP; + } + + /** + Return an operation which finds documents that satisfy given criteria. + + The criteria are specified as a Boolean expression string. + Call `execute()` on the returned operation object to execute it and get + a `DocResult` object that gives access to the documents. Specify additional + query parameters, such as ordering of the documents, using chained methods + of `CollectionFind` class before making the final call to `execute()`. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `CollectionFind` + */ + + CollectionFind find(const string &cond) + { + try { + return CollectionFind(*this, cond); + } + CATCH_AND_WRAP; + } + + /** + Return an operation which adds documents to the collection. + + Specify documents to be added in the same way as when calling + `CollectionAdd::add()` method. Make additional calls to `add()` method on + the returned operation object to add more documents. Call `execute()` + to execute the operation and add all specified documents to the collection. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `CollectionAdd` + */ + + template + CollectionAdd add(Types... args) + { + try { + + CollectionAdd add(*this); + return add.add(args...); + } + CATCH_AND_WRAP; + } + + /** + Return an operation which removes documents satisfying given criteria. + + The criteria are specified as a Boolean expression string. + Call `execute()` on the returned operation object to execute it and remove + the matching documents. Use chained methods of `CollectionRemove` class + before the final call to `execute()` to further limit the set of documents + that are removed. + + @note To remove all documents in the collection, pass "true" as selection + criteria. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `CollectionRemove` + */ + + CollectionRemove remove(const string &cond) + { + try { + return CollectionRemove(*this, cond); + } + CATCH_AND_WRAP; + } + + /** + Return an operation which modifies documents that satisfy given criteria. + + The criteria are specified as a Boolean expression string. + Specify modifications to be applied to each document using chained methods + of `CollectionModify` class on the returned operation object. Call + `execute()` to execute the operation and modify matching documents + as specified. + + @note To modify all documents in the collection, pass "true" as selection + criteria. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `CollectionModify` + */ + + CollectionModify modify(const string &expr) + { + try { + return CollectionModify(*this, expr); + } + CATCH_AND_WRAP; + } + + /** + Return the document with the given id. + + Returns null document if a document with the given id does not exist in + the collection. + */ + + DbDoc getOne(const string &id) + { + return find("_id = :id").bind("id", id).execute().fetchOne(); + } + + /** + Remove the document with the given id. + + Does nothing if a document with the given id does not exist in + the collection. + */ + + Result removeOne(const string &id) + { + return remove("_id = :id").bind("id", id).execute(); + } + + /** + Replace the document with the given id by a new one. + + Specify the new document as either a `DbDoc` object, a JSON string or + an `expr(docexpr)` argument, where `docexpr` is like a JSON string but + field values are given by expressions to be evaluated on the server. + + If a document with the given id does not exist in the collection, nothing + is done and the returned `Result` object indicates that no documents were + modified. + + @note If expressions are used, they can not use named parameters because + it is not possible to bind values prior to execution of `replaceOne()` + operation. + */ + + Result replaceOne(const string &id, Value &&document) + { + try { + return + Collection_detail::add_or_replace_one(id, std::move(document), true); + } + CATCH_AND_WRAP + } + + /** + Add a new document or replace an existing document with the given id. + + Specify the new document as either a `DbDoc` object, a JSON string or + an `expr(docexpr)` argument, where `docexpr` is like a JSON string but + field values are given by expressions to be evaluated on the server. + + If a document with the given id does not exist, the new document is added + to the collection. + + @note If expressions are used, they can not use named parameters because + it is not possible to bind values prior to execution of `addOrReplaceOne()` + operation. + */ + + Result addOrReplaceOne(const string &id, Value &&document) + { + try { + return + Collection_detail::add_or_replace_one(id, std::move(document), false); + } + CATCH_AND_WRAP + } + + /** + Create index on the collection. + + This function creates a named index in the collection using a JSON index + specification. + + @param name name for an index to be created + @param idx_spec index specification as a JSON string + + @see @ref indexing for information on how to define document + collection indexes. + */ + + void createIndex(const string &name, const string &idx_spec) + { + try { + Collection_detail::index_create(name, idx_spec); + } + CATCH_AND_WRAP + } + + /** + Drop index on the collection. + + @param name name for an index to be dropped + */ + + void dropIndex(const string &name) + { + try { + Collection_detail::index_drop(name); + } + CATCH_AND_WRAP + } + + + friend CollectionFind; + friend CollectionAdd; + friend CollectionRemove; + friend CollectionModify; + + ///@cond IGNORE + friend internal::Crud_factory; + ///@endcond +}; + +//------------------------------------------------------------------------------ + + +template<> +inline +void CollectionValidation::do_set(DbDoc schema) +{ + if(m_data.used.test(CollectionValidation::SCHEMA)) + throw_error("Validation schema already set."); + m_data.used.set(CollectionValidation::SCHEMA); + m_data.validation_schema = schema; +} + +template<> +inline +void CollectionValidation::do_set(const char* schema) +{ + do_set(DbDoc(schema)); +} + +template<> +inline +void CollectionValidation::do_set(std::string schema) +{ + do_set(DbDoc(schema)); +} + + +template<> +inline +void CollectionValidation::do_set(Level level) +{ + if(m_data.used.test(CollectionValidation::LEVEL)) + throw_error("Validation level already set."); + m_data.used.set(CollectionValidation::LEVEL); + +#define SCHEMA_VALIDATION_CASE(x,y) case Level::x: m_data.validation_level = #x; break; + + switch (level) { + COLLECTION_VALIDATION_LEVEL(SCHEMA_VALIDATION_CASE) + } +} + +template<> +inline +void CollectionValidation::do_set(std::string level) +{ + if(m_data.used.test(CollectionValidation::LEVEL)) + throw_error("Validation level already set."); + m_data.used.set(CollectionValidation::LEVEL); + + m_data.validation_level = level; + +} + +template<> +inline +void CollectionOptions::do_set(bool reuse) +{ + if(m_data.used[CollectionOptions::REUSE]) + throw_error("Option reuse already set."); + m_data.used.set(CollectionOptions::REUSE); + m_data.reuse = reuse; +} + +template<> +inline +void CollectionOptions::do_set(CollectionValidation validation) +{ + if(m_data.used.test(CollectionOptions::VALIDATION) || + m_data.validation.m_data.used.test(CollectionValidation::LEVEL) || + m_data.validation.m_data.used.test(CollectionValidation::SCHEMA)) + throw_error("Validation already set."); + + m_data.used.set(CollectionOptions::VALIDATION); + m_data.validation.m_data.used.set(CollectionValidation::LEVEL); + m_data.validation.m_data.used.set(CollectionValidation::SCHEMA); + + m_data.validation = validation; +} + + +inline +Collection Schema::createCollection(const string &name) +{ + try { + Schema_detail::create_collection( + name, + CollectionOptions() ); + + return Collection(*this, name); + } + CATCH_AND_WRAP +} + +inline +Collection Schema::createCollection(const string &name, bool reuse) +{ + try { + Schema_detail::create_collection( + name, + CollectionOptions( + CollectionOptions::REUSE, reuse) + ); + + return Collection(*this, name); + } + CATCH_AND_WRAP +} + + +template +inline +Collection Schema::createCollection(const string &name, Rest&&... rest) +{ + try { + Schema_detail::create_collection(name, CollectionOptions(std::forward(rest)...)); + return Collection(*this, name); + } + CATCH_AND_WRAP +} + + +template +inline +void Schema::modifyCollection(const string &name, Opt&&... options) +{ + try { + Schema_detail::modify_collection(name, CollectionOptions(std::forward(options)...)); + } + CATCH_AND_WRAP +} + + + +inline +Collection Schema::getCollection(const string &name, bool check_exists) +{ + Collection coll(*this, name); + if (check_exists && !coll.existsInDatabase()) + throw_error("Collection does not exist"); + return coll; +} + + + +/* + Table object + ============ +*/ + +/** + Represents a table in a schema. + + A `Table` object can be obtained from `Schema::getTable()` + method: + + ~~~~~~ + Schema db; + Table myTable; + + myTable= db.getTable("My Table"); + ~~~~~~ + + or directly constructed as follows: + + ~~~~~~ + Schema db; + Table myTable(db, "My Table"); + ~~~~~~ + + A `Table` object can refer to a plain table or to a view. In the latter case + method `isView()` called on the object returns true. + + When creating a `Table` object, by default no checks are made that + it actually exists in the database. An operation that is executed + on the server and involves such a non-existent table throws + an error. Call `existsInDatabase()` to check the existence of the table. + + @note A `Table` object should be used by at most one thread at a time. It is + not safe to call its methods by several threads simultaneously. It is + responsibility of the user to ensure this using a synchronization mechanism + such as mutexes. + + @ingroup devapi +*/ + +class Table + : protected internal::Sch_object<> +{ +public: + + Table(const Schema &sch, const string &name) + : Sch_object(sch, name) + {} + + Table(const Schema &sch, const string &name, bool is_view) + : Sch_object(sch, name) + { + m_type = is_view ? VIEW : TABLE; + } + + + using Sch_object::getName; + using Sch_object::getSession; + using Sch_object::getSchema; + + + bool existsInDatabase() const; + + + /** + Check if this table object corresponds to a view. + + @note This check might involve communication with the server. + */ + + bool isView(); + + + /** + Get the number of rows in the table. + */ + + uint64_t count() + { + try { + RowResult cnt = select("count(*)").execute(); + return cnt.fetchOne()[0].get(); + } + CATCH_AND_WRAP + } + + + /* + CRUD operations + --------------- + */ + + /** + Return an operation which inserts rows into the full table without + restricting the columns. + + Specify rows to be inserted using methods of `TableInsert` class chained + on the returned operation object. Call `execute()` to execute the operation + and insert the specified rows. + + Each specified row must have the same number of values as the number + of columns of the table. If the value count and the table column count do + not match, server reports error when operation is executed. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `TableInsert` + */ + + TableInsert insert() + { + try { + return TableInsert(*this); + } + CATCH_AND_WRAP; + } + + /** + Return an operation which inserts rows into the table restricting + the columns. + + Specify column names as method arguments. Values are inserted only into + the specified columns, other columns are set to null or to column's default + value (depending on the definition of the table). Specify rows to + be inserted using methods of `TableInsert` class chained on the returned + operation object. Call `execute()` to execute the operation and insert + the specified values. + + Each specified row must have the same number of values as the number + of columns listed here. If the value count and the column count do + not match, server reports error when operation is executed. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `TableInsert` + */ + + template + TableInsert insert(const T&... t) + { + try { + return TableInsert(*this, t...); + } + CATCH_AND_WRAP; + } + + /** + Return an operation which selects rows from the table. + + Call `execute()` on the returned operation object to execute it and get + a `RowResult` object that gives access to the rows. Specify query + parameters, such as selection criteria and ordering of the rows, using + chained methods of `TableSelect` class before making the final call to + `execute()`. To project selected rows before returning them in the result, + specify a list of expressions as arguments of this method. These expressions + are evaluated to form a row in the result. An expression can be optionally + followed by "AS " suffix to give a name to the corresponding column + in the result. If no expressions are given, rows are returned as is, without + any projection. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `TableSelect` + */ + + template + TableSelect select(const PROJ&...proj) + { + try { + return TableSelect(*this, proj...); + } + CATCH_AND_WRAP; + } + + /** + Return an operation which removes rows from the table. + + Use chained methods of `TableRemove` class on the returned operation object + to specify the rows to be removed. Call `execute()` to execute the operation + and remove the rows. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `TableRemove` + */ + + TableRemove remove() + { + try { + return TableRemove(*this); + } + CATCH_AND_WRAP; + } + + /** + Return an operation which updates rows in the table. + + Use chained methods of `TableUpdate` class on the returned operation object + to specify which rows should be updated and what modifications to apply + to each of them. Call `execute()` to execute the operation and remove + the rows. + + @note Any errors related to the operation are reported when the operation + is executed, not when it is created. + + @see `TableUpdate` + */ + + TableUpdate update() + { + try { + return TableUpdate(*this); + } + CATCH_AND_WRAP; + } + +private: + + enum { TABLE, VIEW, UNKNOWN } m_type = UNKNOWN; + + friend TableSelect; + friend TableInsert; + friend TableRemove; + friend TableUpdate; + + ///@cond IGNORE + friend internal::Crud_factory; + ///@endcond +}; + + +inline +bool Table::existsInDatabase() const +{ + try { + /* + Note: When checking existence, we also determine if this is a view or + a plain table because this information is fetched from the server when + querying for a list of tables. + */ + Schema::TableList list(m_schema, m_name); + auto it = list.begin(); + + if (!(it != list.end())) + return false; + + const_cast(this)->m_type = (*it).isView() ? VIEW : TABLE; + return true; + } + CATCH_AND_WRAP +} + + +inline +bool Table::isView() +{ + try { + /* + If view status was not determined yet, do existence check which + determines it as a side effect. + */ + if (UNKNOWN == m_type) + if (!existsInDatabase()) + throw_error("Table does not exist"); + return VIEW == m_type; + } + CATCH_AND_WRAP +} + + +inline +Table Schema::getTable(const string &name, bool check_exists) +{ + Table tbl(*this, name); + if (check_exists && !tbl.existsInDatabase()) + throw_error("Table does not exist"); + return tbl; +} + + +inline +Table Schema::getCollectionAsTable(const string &name, bool check_exists) +{ + if (check_exists && !getCollection(name).existsInDatabase()) + throw_error("Collection does not exist"); + return { *this, name }; +} + + +inline +uint64_t Collection::count() +{ + return m_schema.getCollectionAsTable(m_name).count(); +} + + +using SqlStatement = internal::SQL_statement; + + +/** + Represents a session which gives access to data stored in a data store. + + A `Session` object can be created from a connection string, from + `SessionSettings` or by directly specifying a host name, TCP/IP port and user + credentials. Once created, a session is ready to be used. Session destructor + closes the session and cleans up after it. + + If it is not possible to create a valid session for some reason, errors + are thrown from session constructor. + + Several hosts can be specified by session creation parameters. In that case + a failed connection to one of the hosts triggers a fail-over attempt + to connect to a different host in the list. Only if none of the hosts could + be contacted, session creation fails. + + The fail-over logic tries hosts in the order in which they are specified in + session settings unless explicit priorities are assigned to the hosts. In that + case hosts are tried in the decreasing priority order and for hosts with + the same priority the order in which they are tired is random. + + Once a valid session is created using one of the hosts, the session is bound + to that host and never re-connected again. If the connection gets broken, + the session fails without making any other fail-over attempts. The fail-over + logic is executed only when establishing a new session. + + @note A `Session` object should be used by at most one thread at a time. It is + not safe to call its methods by several threads simultaneously. It is + responsibility of the user to ensure this using a synchronization mechanism + such as mutexes. + + @ingroup devapi +*/ + +class Session + : private internal::Session_detail +{ +public: + + + /** + Create a session specified by a `SessionSettings` object. + */ + + Session(SessionSettings settings) + try + : Session_detail(settings) + {} + CATCH_AND_WRAP + + + /** + Create a session using given session settings. + + This constructor forwards arguments to a `SessionSettings` constructor. + Thus all forms of specifying session options are also directly available + in `Session` constructor. + + Examples: + ~~~~~~ + + Session from_uri("mysqlx://user:pwd@host:port/db?ssl-mode=disabled"); + + + Session from_options("host", port, "user", "pwd", "db"); + + Session from_option_list( + SessionOption::USER, "user", + SessionOption::PWD, "pwd", + SessionOption::HOST, "host", + SessionOption::PORT, port, + SessionOption::DB, "db", + SessionOption::SSL_MODE, SSLMode::DISABLED + ); + ~~~~~~ + + @see `SessionSettings` + */ + + template + Session(T...options) + try + : Session(SessionSettings(options...)) + {}CATCH_AND_WRAP + + + Session(Session &&other) + try + : internal::Session_detail(std::move(other)) + {}CATCH_AND_WRAP + + + Session(Client &client); + + /** + Create a new schema. + + Returns the created schema. Set `reuse` flag to true to return an already + existing schema with the same name. Otherwise, an attempt to create + a schema which already exists throws an error. + */ + + Schema createSchema(const string &name, bool reuse = false) + { + try { + Session_detail::create_schema(name, reuse); + return Schema(*this, name); + } + CATCH_AND_WRAP + } + + /** + Return an object representing a schema with the given name. + + To check if the schema actually exists in the database set `check_existence` + flag to true. Otherwise the returned object can refer to a non-existing + schema. An attempt to use such a non-existing schema in a database operation + throws an error. + + @note Checking the existence of a schema involves communication with + the server. If `check_exists` is false, on the other hand, no I/O is + involved when creating a `Schema` object. + */ + + Schema getSchema(const string &name, bool check_exists = false) + { + Schema sch(*this, name); + if (check_exists && !sch.existsInDatabase()) + throw_error("Schema does not exist"); + return sch; + } + + /** + Get the default schema specified when the session was created. + */ + + Schema getDefaultSchema() + { + return Schema(*this, getDefaultSchemaName()); + } + + /** + Get the name of the default schema specified when the session was created. + */ + + string getDefaultSchemaName() + { + try { + return Session_detail::get_default_schema_name(); + } + CATCH_AND_WRAP + } + + /** + Get a list of all database schemas. + + The returned value can be stored in a container that holds `Schema` objects, + such as `std::vector`. + */ + + SchemaList getSchemas() + { + try { + return Schema_src(*this, "%"); + } + CATCH_AND_WRAP + } + + // TODO: Should we have getSchemaNames() too? + + /** + Drop the named schema. + + Error is thrown if the schema doesn't exist, + */ + + void dropSchema(const string &name) + { + try { + Session_detail::drop_schema(name); + } + CATCH_AND_WRAP + } + + + /** + Return an operation which executes an arbitrary SQL statement. + + Call `execute()` on the returned operation object to execute the statement + and get an `SqlResult` object representing its results. If the SQL statement + contains `?` placeholders, call `bind()` to define their values + prior to the execution. + + @note Errors related to SQL execution are reported when the statement + is executed, not when it is created. + */ + + SqlStatement sql(const string &query) + { + try { + return SqlStatement(this, query); + } + CATCH_AND_WRAP + } + + /** + Start a new transaction. + + Throws error if previously opened transaction is not closed. + */ + + void startTransaction() + { + try { + Session_detail::start_transaction(); + } + CATCH_AND_WRAP + } + + /** + Commit opened transaction, if any. + + Does nothing if no transaction was opened. After committing the + transaction is closed. + */ + + void commit() + { + try { + Session_detail::commit(); + } + CATCH_AND_WRAP + } + + /** + Roll back opened transaction, if any. + + Does nothing if no transaction was opened. Transaction which was + rolled back is closed. To start a new transaction a call to + `startTransaction()` is needed. + */ + + void rollback() + { + try { + Session_detail::rollback(); + } + CATCH_AND_WRAP + } + + /** + Roll back opened transaction to specified savepoint. + + It rolls back to savepoint, but transaction remains active. + Does nothing if no transaction was opened. + + @throws Error If savepoint doesn't exist or is empty. + */ + + void rollbackTo(const string &savepoint) + { + try { + if (savepoint.empty()) + throw_error("Invalid empty save point name"); + Session_detail::rollback(savepoint); + } + CATCH_AND_WRAP + } + + + /** + Sets a named transaction savepoint with a name as + identifier. + + To use savepoints a transaction has to be started using startTransaction(). + + @returns string with savepoint name. + + @note If the current transaction has a savepoint with the same name, + the old savepoint is deleted and a new one is set. + */ + + string setSavepoint(const string &savepoint) + { + try { + if (savepoint.empty()) + throw_error("Invalid empty save point name"); + return Session_detail::savepoint_set(savepoint); + } + CATCH_AND_WRAP + } + + + /** + Creats a transaction savepoint with a generated name as + identifier. + + To use savepoints a transaction has to be started using startTransaction(). + + @returns string with generated savepoint name. + + @note If the current transaction has a savepoint with the same name, + the old savepoint is deleted and a new one is set. + */ + + string setSavepoint() + { + try { + return Session_detail::savepoint_set(); + } + CATCH_AND_WRAP + } + + + /** + Releases savepoint previously added by setSavepoint(). + + @note Releasing savepoint doesn't affect data. + + @throws Error If savepoint doesn't exist. + */ + + void releaseSavepoint(const string &savepoint) + { + try { + if (savepoint.empty()) + throw_error("Invalid empty save point name"); + Session_detail::savepoint_remove(savepoint); + } + CATCH_AND_WRAP + } + + + /** + Close this session. + + After the session is closed, any call to other session's methods + throws an error. + */ + + void close() + { + try { + Session_detail::close(); + } + CATCH_AND_WRAP + } + +protected: + + using internal::Session_detail::m_impl; + +public: + + friend Schema; + friend Collection; + friend Table; + friend Result; + friend RowResult; + + ///@cond IGNORE + friend internal::Session_detail; + friend internal::Crud_factory; + friend internal::Result_detail; + template friend class internal::Sch_object; + ///@endcond +}; + + +/** + Create a client using given client settings. + + Client allows the creation of sessions from a session pool. + + This constructor forwards arguments to a ClientSettings constructor. + Thus all forms of specifying client options are also directly available + in Client constructor. ClientOptions and SessionOptions can be mixed + when construction Client objects + + Examples: + ~~~~~~ + + Client from_uri("mysqlx://user:pwd\@host:port/db?ssl-mode=disabled"); + + + Client from_options("host", port, "user", "pwd", "db"); + + Client from_option_list( + SessionOption::USER, "user", + SessionOption::PWD, "pwd", + SessionOption::HOST, "host", + SessionOption::PORT, port, + SessionOption::DB, "db", + SessionOption::SSL_MODE, SSLMode::DISABLED + ClientOption::POOLING, true, + ClientOption::POOL_MAX_SIZE, 10, + ClientOption::POOL_QUEUE_TIMEOUT, 1000, + ClientOption::POOL_MAX_IDLE_TIME, 500, + ); + ~~~~~~ + + @see ClientSettings +*/ + +class Client : public internal::Client_detail +{ +public: + + Client(ClientSettings settings) + try + : Client_detail(settings) + {} + CATCH_AND_WRAP + + Client(SessionSettings &settings) + try + : Client_detail(settings) + {} + CATCH_AND_WRAP + + template + Client(T...options) + : Client(ClientSettings(options...)) + {} + + + Session getSession() + { + return *this; + } + +}; + + +/* + Session +*/ + +inline +Session::Session(Client &client) +try + : internal::Session_detail(client.get_session_pool()) +{}CATCH_AND_WRAP + +/** + @ingroup devapi + Function to get Session object. + @param p same as needed by Session constructor. + */ + +template +Session getSession(P...p) +{ + return Session(p...); +} + +/** + @ingroup devapi + Function to get Client object. + @param p same as needed by Client constructor. + */ + +template +Client getClient(P...p) +{ + return Client(p...); +} + + +/* + Schema class implementation +*/ + +inline +Schema::Schema(Session &sess, const string &name) + : Schema_detail(sess.m_impl, name) + , m_sess(&sess) +{} + + +template +inline +internal::Sch_object::Sch_object(const Schema &sch, const string &name) + : Base(sch.getSession().m_impl, name) + , m_schema(sch) +{} + + +template +inline +std::shared_ptr +internal::Sch_object::get_session() +{ + assert(m_schema.m_sess); + return m_schema.m_sess->m_impl; +} + + +MYSQLX_ABI_END(2,0) +} // mysqlx + +#endif diff --git a/Libraries/netcpp b/Libraries/netcpp new file mode 160000 index 0000000..6f4675a --- /dev/null +++ b/Libraries/netcpp @@ -0,0 +1 @@ +Subproject commit 6f4675a8655149c54b5f88c268718d7f9667e6e6 diff --git a/Libraries/oneTBB b/Libraries/oneTBB new file mode 160000 index 0000000..bad4c42 --- /dev/null +++ b/Libraries/oneTBB @@ -0,0 +1 @@ +Subproject commit bad4c42be4623b12ac9ff72138e98775555f9153 diff --git a/README.md b/README.md deleted file mode 100644 index ced22ff..0000000 --- a/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# SV Engine ![Build](https://github.com/index1207/SvEngine/actions/workflows/build.yml/badge.svg) ![Lang](https://img.shields.io/badge/language-C++20-blue)
- -SV Engine is simple server engine. It helps develop multi-play game on Unity or Unreal engine and other projects. - -## Features -### -It used [netcpp](https://github.com/index1207/netcpp) library that based on IOCP. - -### Logging -Through `Console` class to log server status. - -### Generated Packet & Packet Handler -Write packet structure with json formated file at `define` directory and run `generate.py` or `PacketGenerator` project to generate **Packet** and **Packet Handler** source file. -All you have to do is only implement Packet Handler methods! - -It will support many languages. - -### Connections -Use connector library to connect to server. -your project can develop through session interaction events being called. - -### Support languages -- **C++** - - ✅ server connector - - ✅ generated packet -- **C#** - - ✅ server connector - - ❌ generated packet - being implementing - - -## Setup -To build this project, clone this repository recursive(`git clone --recursive https://github.com/index1207/SvEngine`) and install python and install other modules. - -### 1. Execute `Setup.bat` - -### 2. Install python & modules -1. `pip install stringcase` \ No newline at end of file diff --git a/SvEngine/SvEngine.vcxproj b/SvEngine/SvEngine.vcxproj deleted file mode 100644 index 7d7f998..0000000 --- a/SvEngine/SvEngine.vcxproj +++ /dev/null @@ -1,257 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - - AnyCPU - - - - 17.0 - Win32Proj - {0e19d820-b6be-4d23-805b-aad9ef0eea69} - SvEngine - 10.0 - - - - StaticLibrary - true - v143 - Unicode - - - StaticLibrary - false - v143 - true - Unicode - - - StaticLibrary - true - v143 - Unicode - - - StaticLibrary - false - v143 - true - Unicode - - - v143 - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)bin\$(Configuration)\ - $(SolutionDir)bin\$(Configuration)\obj\$(ProjectName)\ - - - $(SolutionDir)bin\$(Configuration)\ - $(SolutionDir)bin\$(Configuration)\obj\$(ProjectName)\ - - - $(SolutionDir)bin\$(Configuration)\ - $(SolutionDir)bin\$(Configuration)\obj\$(ProjectName)\ - - - $(SolutionDir)bin\$(Configuration)\ - $(SolutionDir)bin\$(Configuration)\obj\$(ProjectName)\ - - - - Level4 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_HAS_STD_BYTE=0 - true - stdcpp20 - $(ProjectDir)include;$(ProjectDir)PCH;$(SolutionDir)lib\netcpp\include;$(SolutionDir)lib\oneTBB\include;%(AdditionalIncludeDirectories) - true - Use - pch.h - MultiThreadedDebugDLL - - - Console - true - $(SolutionDir)lib\bin\$(Configuration) - ws2_32.lib;netcpp.lib;libmysql.lib;%(AdditionalDependencies) - - - $(SolutionDir)lib\bin\$(Configuration)\;%(AdditionalLibraryDirectories) - ws2_32.lib;netcpp.lib;tbb12_debug.lib;odbc32.lib;%(AdditionalDependencies) - - - - - Level4 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_HAS_STD_BYTE=0 - true - stdcpp20 - $(ProjectDir)include;$(ProjectDir)PCH;$(SolutionDir)lib\netcpp\include;$(SolutionDir)lib\oneTBB\include;%(AdditionalIncludeDirectories) - true - Use - pch.h - MultiThreadedDLL - - - Console - true - true - false - $(SolutionDir)lib\bin\$(Configuration) - ws2_32.lib;netcpp.lib;libmysql.lib;%(AdditionalDependencies) - - - $(SolutionDir)lib\bin\$(Configuration)\;%(AdditionalLibraryDirectories) - ws2_32.lib;netcpp.lib;tbb12.lib;odbc32.lib;%(AdditionalDependencies) - - - - - Level4 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_HAS_STD_BYTE=0 - true - stdcpp20 - $(ProjectDir)include;$(ProjectDir)PCH;$(SolutionDir)lib\netcpp\include;$(SolutionDir)lib\oneTBB\include;%(AdditionalIncludeDirectories) - true - Use - pch.h - MultiThreadedDebugDLL - - - Console - true - $(SolutionDir)lib\bin\$(Configuration) - ws2_32.lib;netcpp.lib;libmysql.lib;%(AdditionalDependencies) - - - $(SolutionDir)lib\bin\$(Configuration)\;%(AdditionalLibraryDirectories) - ws2_32.lib;netcpp.lib;tbb12_debug.lib;odbc32.lib;%(AdditionalDependencies) - - - - - Level4 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_HAS_STD_BYTE=0 - true - stdcpp20 - $(ProjectDir)include;$(ProjectDir)PCH;$(SolutionDir)lib\netcpp\include;$(SolutionDir)lib\oneTBB\include;%(AdditionalIncludeDirectories) - true - Use - pch.h - MultiThreadedDLL - - - Console - true - true - false - $(SolutionDir)lib\bin\$(Configuration) - ws2_32.lib;netcpp.lib;libmysql.lib;%(AdditionalDependencies) - - - $(SolutionDir)lib\bin\$(Configuration)\;%(AdditionalLibraryDirectories) - ws2_32.lib;netcpp.lib;tbb12.lib;odbc32.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SvEngine/include/Database/DBConnectionPool.hpp b/SvEngine/include/Database/DBConnectionPool.hpp deleted file mode 100644 index b4eff59..0000000 --- a/SvEngine/include/Database/DBConnectionPool.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "DBConnection.hpp" - -class DBConnectionPool -{ -public: - DBConnectionPool(); - ~DBConnectionPool(); - - bool Connect(int32 connectionCount, String connectionString); - void Clear(); - - DBConnection* Pop(); - void Push(DBConnection* connection); -private: - SQLHENV _environment = SQL_NULL_HANDLE; - ConcurrencyQueue _connections; -}; - diff --git a/SvEngine/include/Database/DbConnection.hpp b/SvEngine/include/Database/DbConnection.hpp deleted file mode 100644 index 138c02e..0000000 --- a/SvEngine/include/Database/DbConnection.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once -#include -#include - -template -class Statement; - -enum -{ - WVARCHAR_MAX = 4000, - BINARY_MAX = 8000 -}; - -class DBConnection -{ -public: - bool Connect(SQLHENV henv, String connectionString); - void Clear(); - - bool Execute(String query); - bool Fetch(); - int32 GetRowCount(); - void Unbind(); - - template - Statement CreateStatement(String sql) - { - return Statement(this, sql); - } -public: - bool BindParam(int32 paramIdx, bool* value, SQLLEN* idx); - bool BindParam(int32 paramIdx, float* value, SQLLEN* idx); - bool BindParam(int32 paramIdx, double* value, SQLLEN* idx); - bool BindParam(int32 paramIdx, int8* value, SQLLEN* idx); - bool BindParam(int32 paramIdx, int16* value, SQLLEN* idx); - bool BindParam(int32 paramIdx, int32* value, SQLLEN* idx); - bool BindParam(int32 paramIdx, int64* value, SQLLEN* idx); - bool BindParam(int32 paramIdx, TIMESTAMP_STRUCT* value, SQLLEN* idx); - bool BindParam(int32 paramIdx, const WCHAR* str, SQLLEN* idx); - bool BindParam(int32 paramIdx, const BYTE* bin, int32 size, SQLLEN* idx); - - bool BindCol(int32 columnIdx, bool* value, SQLLEN* idx); - bool BindCol(int32 columnIdx, float* value, SQLLEN* idx); - bool BindCol(int32 columnIdx, double* value, SQLLEN* idx); - bool BindCol(int32 columnIdx, int8* value, SQLLEN* idx); - bool BindCol(int32 columnIdx, int16* value, SQLLEN* idx); - bool BindCol(int32 columnIdx, int32* value, SQLLEN* idx); - bool BindCol(int32 columnIdx, int64* value, SQLLEN* idx); - bool BindCol(int32 columnIdx, TIMESTAMP_STRUCT* value, SQLLEN* idx); - bool BindCol(int32 columnIdx, WCHAR* buffer, int32 size, SQLLEN* idx); - bool BindCol(int32 columnIdx, BYTE* buffer, int32 size, SQLLEN* idx); -private: - bool BindParam(int32 paramIndex, SQLSMALLINT cType, SQLSMALLINT sqlType, SQLULEN len, SQLPOINTER ptr, SQLLEN* index); - bool BindCol(int32 columnIndex, SQLSMALLINT cType, SQLULEN len, SQLPOINTER value, SQLLEN* index); - void HandleError(SQLRETURN ret); -private: - SQLHDBC m_connection = SQL_NULL_HANDLE; - SQLHSTMT m_statement = SQL_NULL_HANDLE; -}; - diff --git a/SvEngine/include/Database/Statement.hpp b/SvEngine/include/Database/Statement.hpp deleted file mode 100644 index 370c093..0000000 --- a/SvEngine/include/Database/Statement.hpp +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once - -#include "DBConnection.hpp" - -template struct FullBits { enum { value = (1 << (C - 1)) | FullBits::value }; }; -template<> struct FullBits<1> { enum { value = 1 }; }; -template<> struct FullBits<0> { enum { value = 0 }; }; - -template -class Statement -{ -public: - Statement(DBConnection* connection) : m_connection(connection) - { - memset(m_paramIdx, 0, sizeof(m_paramIdx)); - memset(m_columnIdx, 0, sizeof(m_columnIdx)); - m_paramFlag = 0; - m_columnFlag = 0; - m_connection->Unbind(); - } - Statement(DBConnection* connection, String sql) : Statement(connection) - { - m_query = sql; - } - - bool Validate() - { - return m_paramFlag == FullBits::value && m_columnFlag == FullBits::value; - } - - bool ExecuteQuery() - { - ASSERT_CRASH(Validate()); - return m_connection->Execute(m_query); - } - - bool Next() - { - return m_connection->Fetch(); - } -public: - template - void SetParameter(int32 idx, T& value) - { - m_connection->BindParam(idx+1, &value, &m_paramIdx[idx]); - m_paramFlag |= 1LL << idx; - } - void SetParameter(int32 idx, const WCHAR* value) - { - m_connection->BindParam(idx+1, value, &m_paramIdx[idx]); - m_paramFlag |= 1LL << idx; - } - template - void SetParameter(int32 idx, T(&value)[N]) - { - m_connection->BindParam(idx+1, reinterpret_cast(value), sizeof(T) * N, &m_paramIdx[idx]); - m_paramFlag |= 1LL << idx; - } - template - void SetParameter(int32 idx, T* value, int32 length) - { - m_connection->BindParam(idx+1, reinterpret_cast(value), sizeof(T) * length, &m_paramIdx[idx]); - m_paramFlag |= 1LL << idx; - } - - template - void Bind(int32 idx, T& value) { - m_connection->BindCol(idx+1, &value, &m_columnIdx[idx]); - m_columnFlag |= 1LL << idx; - } - template - void Bind(int32 idx, WCHAR(&value)[N]) - { - m_connection->BindCol(idx+1, value, N*2, & m_columnIdx[idx]); - m_columnFlag |= 1LL << idx; - } - void Bind(int32 idx, WCHAR* value, int32 size) - { - m_connection->BindCol(idx+1, value, size*2, &m_columnIdx[idx]); - m_columnFlag |= 1LL << idx; - } - template - void Bind(int32 idx, T(&value)[N]) - { - m_connection->BindCol(idx+1, value, sizeof(T) * N, &m_columnIdx[idx]); - m_columnFlag |= 1LL << idx; - } -private: - String m_query; - DBConnection* m_connection; - SQLLEN m_paramIdx[paramCount > 0 ? paramCount : 1]; - SQLLEN m_columnIdx[columnCount > 0 ? columnCount : 1]; - uint64 m_paramFlag; - uint64 m_columnFlag; -}; diff --git a/SvEngine/include/Subsystem/Engine.hpp b/SvEngine/include/Subsystem/Engine.hpp deleted file mode 100644 index 96f3322..0000000 --- a/SvEngine/include/Subsystem/Engine.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -class ThreadManager; -class JobSerializer; -class DBConnectionPool; -class JobTimer; - -class Engine { - enum EngineOption - { - WorkTick = 1 - }; -public: - Engine(); - ~Engine(); -public: - void Initialize(); - void Polling(); - - void AddSerializer(JobSerializer* serializer); - void ExecuteThread(int32 io, int32 logic, bool enableMainThrd = true); -public: - __forceinline ThreadManager* GetThreadManager() { return m_threadManager; } - __forceinline DBConnectionPool* GetDBConnectionPool() { return m_dbConnectionPool; } - __forceinline JobTimer* GetJobTimer() { return m_jobTimer; } -private: - void ExecuteLogic(int32 threadCount, std::function tlsInit = [] {}); - void ExecuteIo(int32 threadCount); -private: - ThreadManager* m_threadManager = nullptr; - DBConnectionPool* m_dbConnectionPool = nullptr; - JobTimer* m_jobTimer = nullptr; - - ConcurrencyQueue m_serializerQue; -}; - -extern Engine* GEngine; \ No newline at end of file diff --git a/SvEngine/include/Thread/JobSerializer.hpp b/SvEngine/include/Thread/JobSerializer.hpp deleted file mode 100644 index d4af3fd..0000000 --- a/SvEngine/include/Thread/JobSerializer.hpp +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -using JobCallback = std::function; - -class Job -{ - USE_POOL(Job) -public: - Job(JobCallback&& callback); - - template - inline Job(std::shared_ptr owner, _Ret(T::*method)(Args...), Args&&... args) - { - this->m_callback = [owner, method, args...]() { (owner.get()->*method)(args...); }; - } - __forceinline void operator()() { this->m_callback(); } -private: - JobCallback m_callback; -}; - -class JobTimer -{ - struct JobReserve - { - JobReserve() = default; - JobReserve(uint64 tick, std::shared_ptr serializer, std::shared_ptr job) - : reserveTick(tick), serializer(serializer), job(job) {} - - inline bool operator<(const JobReserve& other) const - { - return reserveTick > other.reserveTick; - } - - uint64 reserveTick; - std::weak_ptr serializer; - std::shared_ptr job; - }; -public: - void Reserve(uint64 tick, std::shared_ptr serializer, std::shared_ptr job); - void Distribute(uint64 now); -private: - ConcurrencyPriorityQueue m_jobs; -}; - -class JobSerializer : public std::enable_shared_from_this -{ -public: - JobSerializer(); -public: - void Launch(JobCallback&& callback); - void Launch(uint64 delay, JobCallback&& callback); - - template - inline void Launch(_Ret(T::*method)(Args...), Args... args) - { - auto owner = std::static_pointer_cast(shared_from_this()); - auto job = MakeShared(owner, method, std::forward(args)...); - if constexpr (_Dly) - { - if (auto* jobTimer = GEngine->GetJobTimer()) - jobTimer->Reserve(_Dly, shared_from_this(), job); - } - else m_jobs.push(job); - } - template - inline void Launch(int64 delay, _Ret(T::*method)(Args...), Args... args) - { - auto owner = std::static_pointer_cast(shared_from_this()); - auto job = MakeShared(owner, method, std::forward(args)...); - if (auto* jobTimer = GEngine->GetJobTimer()) - jobTimer->Reserve(delay, shared_from_this(), job); - } - - void Push(std::shared_ptr job); - void Flush(); -private: - ConcurrencyQueue> m_jobs; -}; \ No newline at end of file diff --git a/SvEngine/include/Thread/TLSStorage.hpp b/SvEngine/include/Thread/TLSStorage.hpp deleted file mode 100644 index 31126e2..0000000 --- a/SvEngine/include/Thread/TLSStorage.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -extern thread_local uint16 LThreadId; -extern thread_local class JobSerializer* LCurrentSerializer; \ No newline at end of file diff --git a/SvEngine/include/Thread/ThreadManager.hpp b/SvEngine/include/Thread/ThreadManager.hpp deleted file mode 100644 index f09ac3c..0000000 --- a/SvEngine/include/Thread/ThreadManager.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -class ThreadManager -{ - using CallbackType = std::function; -public: - ThreadManager(); - ~ThreadManager(); -public: - void Launch(CallbackType callback, CallbackType init = [] {}); - void Join(); - void Terminate(); -public: - static void Initialize(); -private: - ConcurrencyVector m_threads; -}; - diff --git a/SvEngine/include/util/String.hpp b/SvEngine/include/util/String.hpp deleted file mode 100644 index d14831a..0000000 --- a/SvEngine/include/util/String.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "Types.hpp" -#include - -String ToUnicodeString(std::string_view str); - -std::string ToAnsiString(StringView str); - -String UUIDv4() noexcept; - -String Timestamp(); - -Vector Split(StringView str, WCHAR del); \ No newline at end of file diff --git a/SvEngine/src/Database/DBConnectionPool.cpp b/SvEngine/src/Database/DBConnectionPool.cpp deleted file mode 100644 index fb4e010..0000000 --- a/SvEngine/src/Database/DBConnectionPool.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "pch.h" -#include "Database/DBConnectionPool.hpp" - -DBConnectionPool::DBConnectionPool() -{ - -} - -DBConnectionPool::~DBConnectionPool() -{ - Clear(); -} - -bool DBConnectionPool::Connect(int32 connectionCount, String connectionString) -{ - if (::SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &_environment) != SQL_SUCCESS) - return false; - - if (::SQLSetEnvAttr(_environment, SQL_ATTR_ODBC_VERSION, reinterpret_cast(SQL_OV_ODBC3), 0) != SQL_SUCCESS) - return false; - - for (int32 i = 0; i < connectionCount; i++) - { - DBConnection* connection = new DBConnection; - if (connection->Connect(_environment, connectionString) == false) - return false; - - _connections.push(connection); - } - - return true; -} - -void DBConnectionPool::Clear() -{ - if (_environment != SQL_NULL_HANDLE) - { - ::SQLFreeHandle(SQL_HANDLE_ENV, _environment); - _environment = SQL_NULL_HANDLE; - } - - while (_connections.empty()) - { - DBConnection* connection = nullptr; - if (_connections.try_pop(connection)) - delete connection; - } - - _connections.clear(); -} - -DBConnection* DBConnectionPool::Pop() -{ - if (_connections.empty()) - return nullptr; - - DBConnection* connection = nullptr; - _connections.try_pop(connection); - return connection; -} - -void DBConnectionPool::Push(DBConnection* connection) -{ - _connections.push(connection); -} diff --git a/SvEngine/src/Database/DbConnection.cpp b/SvEngine/src/Database/DbConnection.cpp deleted file mode 100644 index 44460ae..0000000 --- a/SvEngine/src/Database/DbConnection.cpp +++ /dev/null @@ -1,268 +0,0 @@ -#include "pch.h" -#include "Database/DBConnection.hpp" - -bool DBConnection::Connect(SQLHENV henv, String connectionString) -{ - if (::SQLAllocHandle(SQL_HANDLE_DBC, henv, &m_connection) != SQL_SUCCESS) - return false; - - WCHAR stringBuffer[MAX_PATH] = { 0 }; - std::copy(connectionString.begin(), connectionString.end(), stringBuffer); - - WCHAR resultString[MAX_PATH] = { 0 }; - SQLSMALLINT resultStringLen = 0; - - SQLRETURN ret = ::SQLDriverConnectW( - m_connection, - NULL, - reinterpret_cast(stringBuffer), - _countof(stringBuffer), - OUT reinterpret_cast(resultString), - _countof(resultString), - OUT & resultStringLen, - SQL_DRIVER_NOPROMPT - ); - - if (::SQLAllocHandle(SQL_HANDLE_STMT, m_connection, &m_statement) != SQL_SUCCESS) - return false; - - return (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO); -} - -void DBConnection::Clear() -{ - if (m_connection != SQL_NULL_HANDLE) - { - ::SQLFreeHandle(SQL_HANDLE_DBC, m_connection); - m_connection = SQL_NULL_HANDLE; - } - - if (m_statement != SQL_NULL_HANDLE) - { - ::SQLFreeHandle(SQL_HANDLE_STMT, m_statement); - m_statement = SQL_NULL_HANDLE; - } -} - -bool DBConnection::Execute(String query) -{ - SQLRETURN ret = ::SQLExecDirectW(m_statement, (SQLWCHAR*)query.data(), SQL_NTSL); - if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) - return true; - - HandleError(ret); - return false; -} - -bool DBConnection::Fetch() -{ - SQLRETURN ret = ::SQLFetch(m_statement); - - switch (ret) - { - case SQL_SUCCESS: - case SQL_SUCCESS_WITH_INFO: - return true; - case SQL_NO_DATA: - return false; - case SQL_ERROR: - HandleError(ret); - return false; - default: - return true; - } -} - -int32 DBConnection::GetRowCount() -{ - SQLLEN count = 0; - SQLRETURN ret = ::SQLRowCount(m_statement, OUT &count); - - if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) - return static_cast(count); - - return -1; -} - -void DBConnection::Unbind() -{ - ::SQLFreeStmt(m_statement, SQL_UNBIND); - ::SQLFreeStmt(m_statement, SQL_RESET_PARAMS); - ::SQLFreeStmt(m_statement, SQL_CLOSE); -} - -bool DBConnection::BindParam(int32 paramIdx, bool* value, SQLLEN* idx) -{ - return BindParam(paramIdx, SQL_C_TINYINT, SQL_TINYINT, sizeof(bool), value, idx); -} - -bool DBConnection::BindParam(int32 paramIdx, float* value, SQLLEN* idx) -{ - return BindParam(paramIdx, SQL_C_FLOAT, SQL_FLOAT, 0, value, idx); -} - -bool DBConnection::BindParam(int32 paramIdx, double* value, SQLLEN* idx) -{ - return BindParam(paramIdx, SQL_C_DOUBLE, SQL_DOUBLE, 0, value, idx); -} - -bool DBConnection::BindParam(int32 paramIdx, int8* value, SQLLEN* idx) -{ - return BindParam(paramIdx, SQL_C_TINYINT, SQL_TINYINT, sizeof(int8), value, idx); -} - -bool DBConnection::BindParam(int32 paramIdx, int16* value, SQLLEN* idx) -{ - return BindParam(paramIdx, SQL_C_SHORT, SQL_SMALLINT, sizeof(int16), value, idx); -} - -bool DBConnection::BindParam(int32 paramIdx, int32* value, SQLLEN* idx) -{ - return BindParam(paramIdx, SQL_C_LONG, SQL_INTEGER, sizeof(int32), value, idx); -} - -bool DBConnection::BindParam(int32 paramIdx, int64* value, SQLLEN* idx) -{ - return BindParam(paramIdx, SQL_C_SBIGINT, SQL_BIGINT, sizeof(int64), value, idx); -} - -bool DBConnection::BindParam(int32 paramIdx, TIMESTAMP_STRUCT* value, SQLLEN* idx) -{ - return BindParam(paramIdx, SQL_C_TIMESTAMP, SQL_TIMESTAMP, sizeof(TIMESTAMP_STRUCT), value, idx); -} - -bool DBConnection::BindParam(int32 paramIdx, const WCHAR* str, SQLLEN* idx) -{ - SQLLEN size = (wcslen(str)+1) * 2; - *idx = SQL_NTSL; - - if (size > WVARCHAR_MAX) - return BindParam(paramIdx, SQL_C_WCHAR, SQL_WLONGVARCHAR, size, (SQLPOINTER)str, idx); - return BindParam(paramIdx, SQL_C_WCHAR, SQL_WVARCHAR, size, (SQLPOINTER)str, idx); -} - -bool DBConnection::BindParam(int32 paramIdx, const BYTE* bin, int32 size, SQLLEN* idx) -{ - if (bin == nullptr) - { - *idx = SQL_NULL_DATA; - size = 1; - } - else - *idx = size; - - if (size > BINARY_MAX) - return BindParam(paramIdx, SQL_C_BINARY, SQL_LONGVARBINARY, size, const_cast(bin), idx); - return BindParam(paramIdx, SQL_C_BINARY, SQL_VARBINARY, size, const_cast(bin), idx); -} - -bool DBConnection::BindCol(int32 columnIdx, bool* value, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_TINYINT, sizeof(bool), value, idx); -} - -bool DBConnection::BindCol(int32 columnIdx, float* value, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_FLOAT, sizeof(float), value, idx); -} - -bool DBConnection::BindCol(int32 columnIdx, double* value, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_DOUBLE, sizeof(double), value, idx); -} - -bool DBConnection::BindCol(int32 columnIdx, int8* value, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_TINYINT, sizeof(int8), value, idx); -} - -bool DBConnection::BindCol(int32 columnIdx, int16* value, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_SHORT, sizeof(int16), value, idx); -} - -bool DBConnection::BindCol(int32 columnIdx, int32* value, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_LONG, sizeof(int32), value, idx); -} - -bool DBConnection::BindCol(int32 columnIdx, int64* value, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_SBIGINT, sizeof(int64), value, idx); -} - -bool DBConnection::BindCol(int32 columnIdx, TIMESTAMP_STRUCT* value, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_TIMESTAMP, sizeof(TIMESTAMP_STRUCT), value, idx); -} - -bool DBConnection::BindCol(int32 columnIdx, WCHAR* buffer, int32 size, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_WCHAR, size, buffer, idx); -} - -bool DBConnection::BindCol(int32 columnIdx, BYTE* buffer, int32 size, SQLLEN* idx) -{ - return BindCol(columnIdx, SQL_C_BINARY, size, buffer, idx); -} - -bool DBConnection::BindParam(int32 paramIndex, SQLSMALLINT cType, SQLSMALLINT sqlType, SQLULEN len, SQLPOINTER ptr, SQLLEN* index) -{ - SQLRETURN ret = ::SQLBindParameter(m_statement, static_cast(paramIndex), SQL_PARAM_INPUT, cType, sqlType, len, 0, ptr, 0, index); - if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) - { - HandleError(ret); - return false; - } - - return true; -} - -bool DBConnection::BindCol(int32 columnIndex, SQLSMALLINT cType, SQLULEN len, SQLPOINTER value, SQLLEN* index) -{ - SQLRETURN ret = ::SQLBindCol(m_statement, static_cast(columnIndex), cType, value, len, index); - if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) - { - HandleError(ret); - return false; - } - - return true; -} - -void DBConnection::HandleError(SQLRETURN ret) -{ - if (ret == SQL_SUCCESS) - return; - - SQLSMALLINT index = 1; - SQLWCHAR sqlState[MAX_PATH] = { 0 }; - SQLINTEGER nativeErr = 0; - SQLWCHAR errMsg[MAX_PATH] = { 0 }; - SQLSMALLINT msgLen = 0; - SQLRETURN errorRet = 0; - - while (true) - { - errorRet = ::SQLGetDiagRecW( - SQL_HANDLE_STMT, - m_statement, - index, - sqlState, - OUT &nativeErr, - errMsg, - _countof(errMsg), - OUT &msgLen - ); - - if (errorRet == SQL_NO_DATA) - break; - - if (errorRet != SQL_SUCCESS && errorRet != SQL_SUCCESS_WITH_INFO) - break; - - Console::Error(Category::Database, errMsg); - - index++; - } -} diff --git a/SvEngine/src/Database/Statement.cpp b/SvEngine/src/Database/Statement.cpp deleted file mode 100644 index 4cac1cb..0000000 --- a/SvEngine/src/Database/Statement.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "pch.h" -#include "Database/Statement.hpp" diff --git a/SvEngine/src/Subsystem/Engine.cpp b/SvEngine/src/Subsystem/Engine.cpp deleted file mode 100644 index a220d8b..0000000 --- a/SvEngine/src/Subsystem/Engine.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// -// Created by han93 on 2023-12-20. -// -#include "pch.h" -#include "Subsystem/Engine.hpp" - -#include "Thread/ThreadManager.hpp" -#include "Thread/JobSerializer.hpp" -#include "Database/DBConnectionPool.hpp" - -Engine::Engine() -{ - Console::Initialize(); - - net::Option::Autorun = false; - net::Option::Timeout = WorkTick; -} - -Engine::~Engine() -{ - delete m_threadManager; - delete m_dbConnectionPool; - delete m_jobTimer; -} - -void Engine::AddSerializer(JobSerializer* serializer) -{ - m_serializerQue.push(serializer); -} - -void Engine::ExecuteThread(int32 io, int32 logic, bool enableMainThrd) -{ - ExecuteLogic(logic); - ExecuteIo(io); - if (enableMainThrd) - Polling(); -} - -void Engine::Initialize() -{ - m_threadManager = new ThreadManager; - m_dbConnectionPool = new DBConnectionPool; - m_jobTimer = new JobTimer; -} - -void Engine::ExecuteLogic(int32 threadCount, std::function tlsInit) -{ - for (int i = 0; i < threadCount; ++i) - { - m_threadManager->Launch([=]() - { - Polling(); - }, tlsInit); - } -} - -void Engine::ExecuteIo(int32 threadCount) -{ - for (int i = 0; i < threadCount; ++i) - { - m_threadManager->Launch([=]() - { - while (true) - { - IoSystem::instance().worker(); // IOCP I/O Worker - }; - }); - } -} - -void Engine::Polling() -{ - while (true) - { - m_jobTimer->Distribute(GetTickCount64()); - - if (!m_serializerQue.empty()) - { - JobSerializer* jobSerializer; - if (m_serializerQue.try_pop(jobSerializer)) - { - jobSerializer->Flush(); - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(WorkTick)); - } -} diff --git a/SvEngine/src/Thread/JobSerializer.cpp b/SvEngine/src/Thread/JobSerializer.cpp deleted file mode 100644 index dba63f7..0000000 --- a/SvEngine/src/Thread/JobSerializer.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "pch.h" -#include "Thread/JobSerializer.hpp" - -JobSerializer::JobSerializer() -{ - GEngine->AddSerializer(this); -} - -void JobSerializer::Launch(JobCallback&& callback) -{ - m_jobs.push(MakeShared(std::move(callback))); -} - -void JobSerializer::Launch(uint64 delay, JobCallback&& callback) -{ - auto job = MakeShared(std::move(callback)); - if (auto* jobTimer = GEngine->GetJobTimer()) - jobTimer->Reserve(delay, shared_from_this(), job); -} - -void JobSerializer::Push(std::shared_ptr job) -{ - m_jobs.push(job); -} - -void JobSerializer::Flush() -{ - while (!m_jobs.empty()) - { - std::shared_ptr job; - if (m_jobs.try_pop(job)) - (*job)(); - } - GEngine->AddSerializer(this); -} - -void JobTimer::Reserve(uint64 tick, std::shared_ptr serializer, std::shared_ptr job) -{ - m_jobs.push({ GetTickCount64() + tick, serializer, job }); -} - -void JobTimer::Distribute(uint64 now) -{ - while (!m_jobs.empty()) - { - JobReserve jobReserve; - if (m_jobs.try_pop(jobReserve)) - { - if (now < jobReserve.reserveTick) - { - m_jobs.push(jobReserve); - break; - } - else if (auto serializer = jobReserve.serializer.lock()) - serializer->Push(jobReserve.job); - } - } -} - -Job::Job(JobCallback&& callback) : m_callback(std::forward(callback)) -{ -} diff --git a/SvEngine/src/Thread/TLSStorage.cpp b/SvEngine/src/Thread/TLSStorage.cpp deleted file mode 100644 index 395f67a..0000000 --- a/SvEngine/src/Thread/TLSStorage.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include -#include - -thread_local uint16 LThreadId = 0; -thread_local JobSerializer* LCurrentSerializer = nullptr; \ No newline at end of file diff --git a/SvEngine/src/Thread/ThreadManager.cpp b/SvEngine/src/Thread/ThreadManager.cpp deleted file mode 100644 index acdae86..0000000 --- a/SvEngine/src/Thread/ThreadManager.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "pch.h" -#include "Thread/ThreadManager.hpp" -#include "Thread/JobSerializer.hpp" - -ThreadManager::ThreadManager() -{ - Initialize(); -} - -ThreadManager::~ThreadManager() -{ - Join(); -} - -void ThreadManager::Launch(CallbackType callback, CallbackType tlsInit) -{ - m_threads.push_back(new std::thread([=] { - Initialize(); - tlsInit(); - callback(); - })); -} - -void ThreadManager::Join() -{ - for (auto t : m_threads) - { - t->join(); - } -} - -void ThreadManager::Terminate() -{ - for (auto& t : m_threads) - delete t; - m_threads.clear(); -} - -void ThreadManager::Initialize() -{ - static std::atomic s_threadId = 1; - LThreadId = s_threadId.fetch_add(1); -} \ No newline at end of file diff --git a/tools/PacketGenerator/PacketGenerator.pyproj b/Tools/PacketGenerator/PacketGenerator.pyproj similarity index 87% rename from tools/PacketGenerator/PacketGenerator.pyproj rename to Tools/PacketGenerator/PacketGenerator.pyproj index ab8b1e5..2fde5f9 100644 --- a/tools/PacketGenerator/PacketGenerator.pyproj +++ b/Tools/PacketGenerator/PacketGenerator.pyproj @@ -4,7 +4,8 @@ 2.0 1cbc2443-d0a8-4ed5-ac39-1782d2001b4e . - execute.py + + . @@ -24,6 +25,11 @@ true false + + true + false + bin\Debug-static\ + diff --git a/tools/PacketGenerator/execute.py b/Tools/PacketGenerator/execute.py similarity index 90% rename from tools/PacketGenerator/execute.py rename to Tools/PacketGenerator/execute.py index 2c4f6c3..26b3121 100644 --- a/tools/PacketGenerator/execute.py +++ b/Tools/PacketGenerator/execute.py @@ -10,6 +10,9 @@ def arg_as_list(s): raise argparse.ArgumentTypeError("Argument \"%s\" is not a list" % (s)) return v +if not os.path.exists("generated"): + os.makedirs("generated") + parser = argparse.ArgumentParser() parser.add_argument('-s', '--server_path', default='', action='store', dest='server_path', help='server project directory path') parser.add_argument('-c', '--client_path', default='', action='store', dest='client_path', help='client project directory path') @@ -17,7 +20,7 @@ def arg_as_list(s): args = parser.parse_args() subprocess.call(['python', 'generate.py', '-l', 'cpp', '-p', args.server_path+'message/', '-n', args.namespace], shell=True) -# # subprocess.call(['python', 'generate.py', '-l', 'csharp'], shell=True) +# subprocess.call(['python', 'generate.py', '-l', 'csharp'], shell=True) if args.server_path != '': dest = args.server_path + f'generated/{args.namespace}' diff --git a/tools/PacketGenerator/generate.py b/Tools/PacketGenerator/generate.py similarity index 93% rename from tools/PacketGenerator/generate.py rename to Tools/PacketGenerator/generate.py index a457f68..6caee89 100644 --- a/tools/PacketGenerator/generate.py +++ b/Tools/PacketGenerator/generate.py @@ -26,7 +26,7 @@ class Format: #include "Network/Packet.h" #elif __SERVER__ #include "Network/Packet.hpp" -#include "Util/Types.hpp" +#include "Types.hpp" #endif #include @@ -63,18 +63,17 @@ class Format: class Session; #endif -#define BIND_HANDLER(pckname, buffer, id) std::bind(pckname##PacketHandler, std::placeholders::_1, Packet::ParseFrom(buffer, id)); namespace gen {{ namespace {1} {{ class PacketHandler {{ - using Handler = TFunction)>; + using Handler = TFunction; public: - static Handler GetHandler(uint16 id, std::span buffer) + static Handler HandlePacket(Session* session, std::span buffer) {{ - switch (id) + switch (Packet::GetPacketId(buffer)) {{ case PacketId::NONE: break; @@ -84,13 +83,6 @@ class PacketHandler }} return nullptr; }} - static bool HandlePacket(TSharedPtr session, uint16 id, std::span buffer) - {{ - auto handler = GetHandler(id, buffer); - if (!handler || !session) - return false; - return handler(session); - }} {3} }}; }} @@ -411,8 +403,8 @@ def DeleteAllFiles(filePath): outputHandler[i] = cppFormat.handler.format( '\n'.join(f'#include "generated/{args.namespace}/{(value.rstrip(".json"))}.gen.hpp"' for value in defList), args.namespace, - '\n'.join(f'\t\t\tcase {stringcase.constcase(value)}:\n\t\t\t\treturn BIND_HANDLER({value}, buffer, id);' for value in messageNameList[i]), - '\n'.join(str('\t\tstatic bool '+value+f'(TSharedPtr session, TSharedPtr<{(messageNameList[i][handlerList[i].index(value)])}> packet);') for value in handlerList[i]) #handlers + '\n'.join(f'\t\t\tcase {stringcase.constcase(value)}:\n\t\t\t\t{value}PacketHandler(session, Packet::ParseFrom<{value}>(buffer));\n\t\t\t\tbreak;' for value in messageNameList[i]), + '\n'.join(str('\t\tstatic bool '+value+f'(Session* session, TSharedPtr<{(messageNameList[i][handlerList[i].index(value)])}> packet);') for value in handlerList[i]) #handlers ) diff --git a/lib/netcpp b/lib/netcpp deleted file mode 160000 index f6afb47..0000000 --- a/lib/netcpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f6afb47e0576f87fa65b293ed3d849c93c577db2 diff --git a/lib/oneTBB b/lib/oneTBB deleted file mode 160000 index ca7f580..0000000 --- a/lib/oneTBB +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ca7f5801460c5a85afd793429a73575b5d7c6094 diff --git a/setup.bat b/setup.bat index 275f59d..fbc7e52 100644 --- a/setup.bat +++ b/setup.bat @@ -1,29 +1,31 @@ -@echo off +@ECHO OFF @rem install python module pip install stringcase +SET LIB_DIR=.\Libraries\ +SET BIN_DIR=.\Binaries\ + @rem build libraries -mkdir .\lib\bin\Debug -mkdir .\lib\bin\Release +IF NOT EXIST "%BIN_DIR%\Debug" ( MKDIR %BIN_DIR%\Debug ) +IF NOT EXIST "%BIN_DIR%\Release" ( MKDIR %BIN_DIR%\Release ) -call :build Debug -call :build Release +CALL :build Debug +CALL :build Release EXIT /B %ERRORLEVEL% :build -cd lib\netcpp +CD %LIB_DIR%\netcpp cmake . && cmake --build . --target netcpp --config %~1 -cd ..\oneTBB +CD ..\oneTBB cmake . && cmake --build . --target tbb --config %~1 -cd ..\..\ -for /r .\lib\oneTBB\ %%i in (*.lib, *.dll) do ( - copy "%%i" "lib\bin\%~1\" +CD ..\..\ +for /r %LIB_DIR%\netcpp\ %%i IN (*.lib, *.dll, *.pdb) do ( + copy "%%i" "%BIN_DIR%\%~1\" del "%%i" ) - -for /r .\lib\netcpp\ %%i in (*.lib) do ( - copy "%%i" "lib\bin\%~1\" - del "%%i" +FOR /r %LIB_DIR%\oneTBB\ %%i IN (*.lib, *.dll, *.pdb) do ( + COPY "%%i" "%BIN_DIR%\%~1\" + DEL "%%i" ) EXIT /B 0 \ No newline at end of file diff --git a/tools/PacketGenerator/PacketGenerator.pyproj.user b/tools/PacketGenerator/PacketGenerator.pyproj.user deleted file mode 100644 index 46e5748..0000000 --- a/tools/PacketGenerator/PacketGenerator.pyproj.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - ShowAllFiles - - \ No newline at end of file