1 /// Internal - Protocol-related data types.
2 module mysql.protocol.extra_types;
3 
4 import std.exception;
5 import std.variant;
6 
7 import mysql.exceptions;
8 import mysql.protocol.sockets;
9 import mysql.types;
10 
11 struct SQLValue
12 {
13 	bool isNull;
14 	bool isIncomplete;
15 	MySQLVal _value;
16 
17 	@safe:
18 	// empty template as a template and non-template won't be added to the same overload set
19 	@property inout(MySQLVal) value()() inout
20 	{
21 		enforce!MYX(!isNull, "SQL value is null");
22 		enforce!MYX(!isIncomplete, "SQL value not complete");
23 		return _value;
24 	}
25 
26 	@property void value(T)(T value)
27 	{
28 		enforce!MYX(!isNull, "SQL value is null");
29 		enforce!MYX(!isIncomplete, "SQL value not complete");
30 		_value = value;
31 	}
32 
33 	pure const nothrow invariant()
34 	{
35 		isNull && assert(!isIncomplete);
36 		isIncomplete && assert(!isNull);
37 	}
38 }
39 
40 
41 /// Length Coded Binary Value
42 struct LCB
43 {
44 	@safe:
45 	/// True if the `LCB` contains a null value
46 	bool isNull;
47 
48 	/// True if the packet that created this `LCB` didn't have enough bytes
49 	/// to store a value of the size specified. More bytes have to be fetched from the server.
50 	bool isIncomplete;
51 
52 	/// Number of bytes needed to store the value (Extracted from the LCB header. The header byte is not included)
53 	ubyte numBytes;
54 
55 	/// Number of bytes total used for this `LCB`
56 	@property ubyte totalBytes() pure const nothrow
57 	{
58 		return cast(ubyte)(numBytes <= 1 ? 1 : numBytes+1);
59 	}
60 
61 	/// The decoded value. This is always 0 if `isNull` or `isIncomplete` is set.
62 	ulong value;
63 
64 	pure const nothrow invariant()
65 	{
66 		if(isIncomplete)
67 		{
68 			assert(!isNull);
69 			assert(value == 0);
70 			assert(numBytes > 0);
71 		}
72 		else if(isNull)
73 		{
74 			assert(!isIncomplete);
75 			assert(value == 0);
76 			assert(numBytes == 0);
77 		}
78 		else
79 		{
80 			assert(!isNull);
81 			assert(!isIncomplete);
82 			assert(numBytes > 0);
83 		}
84 	}
85 }
86 
87 /// Length Coded String
88 ///
89 /// Dummy struct just to tell what value we are using.
90 /// We don't need to store anything here as the result is always a string.
91 struct LCS
92 {
93 	// Nothing
94 }