1 /** 2 * Copyright © DiamondMVC 2018 3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module diamond.data.mapping.engines.mysql.generators.insertgenerator; 7 8 import std..string : format; 9 import std.traits : hasUDA, FieldNameTuple; 10 import std.algorithm : map; 11 import std.array : join, array; 12 13 import diamond.core.traits; 14 import diamond.data.mapping.attributes; 15 import diamond.data.mapping.engines.mysql.model : IMySqlModel; 16 17 package(diamond.data): 18 /** 19 * Generates the insert function for a database model. 20 * Returns: 21 * The insert function string to use with mixin. 22 */ 23 string generateInsert(T : IMySqlModel)() 24 { 25 import models; 26 27 string s = q{ 28 { 29 static const sql = "INSERT INTO `%s` (%s) VALUES (%s)"; 30 auto params = getParams(%s); 31 32 size_t index; 33 34 %s 35 36 %s 37 } 38 }; 39 40 string[] columns; 41 string[] paramsInserts; 42 string idName; 43 string idType; 44 string execution; 45 46 { 47 mixin HandleFields!(T, q{{ 48 enum hasId = hasUDA!({{fullName}}, DbId); 49 50 static if (hasId) 51 { 52 idName = "{{fieldName}}"; 53 idType = typeof({{fullName}}).stringof; 54 } 55 }}); 56 mixin(handleThem()); 57 58 if (idName) 59 { 60 execution = "model.%s = MySql.scalarInsertRaw!%s(sql, params);".format(idName, idType); 61 } 62 else 63 { 64 execution = "MySql.executeRaw(sql, params);"; 65 } 66 } 67 68 { 69 mixin HandleFields!(T, q{{ 70 enum hasNoMap = hasUDA!({{fullName}}, DbNoMap); 71 enum hasId = hasUDA!({{fullName}}, DbId); 72 73 static if (!hasNoMap && !hasId) 74 { 75 columns ~= "`{{fieldName}}`"; 76 } 77 }}); 78 mixin(handleThem()); 79 } 80 81 if (!columns || !columns.length) 82 { 83 return ""; 84 } 85 86 { 87 mixin HandleFields!(T, q{{ 88 enum hasNoMap = hasUDA!({{fullName}}, DbNoMap); 89 enum hasId = hasUDA!({{fullName}}, DbId); 90 91 static if (!hasNoMap && !hasId) 92 { 93 enum hasEnum = hasUDA!({{fullName}}, DbEnum); 94 enum hasTimestamp = hasUDA!({{fullName}}, DbTimestamp); 95 96 static if (hasEnum) 97 { 98 paramsInserts ~= "params[index++] = cast(string)model.{{fieldName}};"; 99 } 100 else static if (hasTimestamp) 101 { 102 paramsInserts ~= ` 103 model.timestamp = Clock.currTime().asDateTime(); 104 params[index++] = model.timestamp; 105 `; 106 } 107 else static if (is(typeof({{fullName}}) == bool)) 108 { 109 paramsInserts ~= "params[index++] = cast(ubyte)model.{{fieldName}};"; 110 } 111 else 112 { 113 paramsInserts ~= "params[index++] = model.{{fieldName}};"; 114 } 115 } 116 }}); 117 mixin(handleThem()); 118 } 119 120 if (!paramsInserts || !paramsInserts.length) 121 { 122 return ""; 123 } 124 125 return s.format(T.table, columns.join(","), columns.map!(c => "?").array.join(","), columns.length, paramsInserts.join("\r\n"), execution); 126 }