1 /** 2 * Copyright © DiamondMVC 2019 3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module diamond.data.mapping.engines.mssql.mssqlmodel; 7 8 import diamond.core.apptype; 9 10 static if (hasMsSql) 11 { 12 import std.variant : Variant; 13 import std.traits : hasUDA, isSomeString, OriginalType; 14 import std..string : format; 15 16 import vibe.data.serialization : ignore; 17 18 import diamond.data.mapping.engines.mssql.mssqladapter; 19 import diamond.data.mapping.engines.mssql.mssqlentityformatter; 20 import diamond.data.mapping.engines.mssql : dbConnectionString; 21 import diamond.data.mapping.attributes; 22 23 import diamond.database; 24 25 /// Interface for a mssql model. 26 interface IMsSqlModel { } 27 28 import diamond.data.mapping.model; 29 /** 30 * Creates a new mssql model. 31 * Params: 32 * tableName = The name of the table the model is associated with. 33 */ 34 class MsSqlModel(string tableName) : Model, IMsSqlModel 35 { 36 import models; 37 import ddbc; 38 39 private: 40 /// The row. 41 ResultSet _row; 42 /// The index. 43 size_t _index; 44 45 public: 46 /// The name of the table associated with the mssql model. 47 @ignore static const string table = tableName; 48 49 final 50 { 51 /// Creates a new mssql model. 52 this(this TModel)() 53 { 54 super(); 55 56 auto adapter = getMsSqlAdapter!TModel; 57 58 static const formatter = new MsSqlEntityFormatter!TModel; 59 60 auto model = cast(TModel)this; 61 62 mixin("setReader(" ~ formatter.generateRead() ~ ");"); 63 mixin("setInserter(" ~ formatter.generateInsert() ~ ");"); 64 mixin("setUpdater(" ~ formatter.generateUpdate() ~ ");"); 65 mixin("setDeleter(" ~ formatter.generateDelete() ~ ");"); 66 mixin("setReaderRelationship(" ~ formatter.generateReadRelationship() ~ ");"); 67 } 68 69 /** 70 * Retrieves a value from the model's data. 71 * Returns: 72 * The value. 73 */ 74 T retrieve(T, bool nullable = false, bool isEnum = false)() 75 { 76 alias Column = Variant; 77 78 Column value = Column.init; 79 80 static if (nullable && isEnum) 81 { 82 value = retrieveNullableEnumImpl(); 83 84 if (!value.hasValue) 85 { 86 value = T.init; 87 } 88 else 89 { 90 value = cast(T)value.get!(OriginalType!T); 91 } 92 } 93 else static if (isEnum) 94 { 95 value = cast(T)retrieveEnumImpl().get!(OriginalType!T); 96 } 97 else static if (nullable) 98 { 99 value = retrieveNullableImpl(); 100 101 if (!value.hasValue) 102 { 103 value = T.init; 104 } 105 } 106 else static if (is(T == bool)) 107 { 108 value = retrieveBoolImpl(); 109 } 110 else static if (isSomeString!T) 111 { 112 value = retrieveTextImpl(); 113 } 114 else 115 { 116 value = retrieveDefaultImpl(); 117 } 118 119 moveToNextColumn(); 120 121 if (!value.hasValue) 122 { 123 return T.init; 124 } 125 126 return value.get!T; 127 } 128 129 @property 130 { 131 /// Gets the raw mssql row. 132 @ignore ResultSet row() @system { return _row; } 133 134 /// Sets the raw mssql row. 135 @ignore void row(ResultSet newRow) @system 136 { 137 _row = newRow; 138 } 139 } 140 } 141 142 protected: 143 /// Moves to the next column. 144 void moveToNextColumn() 145 { 146 throw new Exception("Not implemented ..."); 147 } 148 149 /// Retrieves a nullable enum value. 150 Variant retrieveNullableEnumImpl() 151 { 152 Variant value = void; 153 154 if (_row.isNull(_index)) 155 { 156 value = Variant.init; 157 } 158 else 159 { 160 value = retrieveTextImpl(); 161 } 162 163 return value; 164 } 165 166 /// Retrieves an enum value. 167 Variant retrieveEnumImpl() 168 { 169 Variant text = retrieveTextImpl(); 170 171 return text; 172 } 173 174 /// Retrieves a nullable value. 175 Variant retrieveNullableImpl() 176 { 177 Variant value = void; 178 179 if (_row.isNull(_index)) 180 { 181 value = Variant.init; 182 } 183 else 184 { 185 value = retrieveDefaultImpl(); 186 } 187 188 return value; 189 } 190 191 /// Retrieves a boolean value. 192 bool retrieveBoolImpl() 193 { 194 return _row.getBoolean(_index); 195 } 196 197 /// Retrieves a text value. 198 string retrieveTextImpl() 199 { 200 return _row.getString(_index); 201 } 202 203 /// Retrieves any kind of value. 204 Variant retrieveDefaultImpl() 205 { 206 return _row.getVariant(_index); 207 } 208 } 209 }