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.updategenerator; 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 update function for a database model. 20 * Returns: 21 * The update function string to use with mixin. 22 */ 23 string generateUpdate(T : IMySqlModel)() 24 { 25 import models; 26 27 string s = q{ 28 { 29 static const sql = "UPDATE `%s` SET %s WHERE `%s` = ?"; 30 auto params = getParams(%s); 31 32 size_t index; 33 34 %s 35 36 %s 37 38 MySql.executeRaw(sql, params); 39 } 40 }; 41 42 string[] columns; 43 string[] paramsUpdates; 44 string idName; 45 string idParams; 46 47 { 48 mixin HandleFields!(T, q{{ 49 enum hasNoMap = hasUDA!({{fullName}}, DbNoMap); 50 enum hasId = hasUDA!({{fullName}}, DbId); 51 52 static if (!hasNoMap && !hasId) 53 { 54 columns ~= "`{{fieldName}}` = ?"; 55 } 56 }}); 57 mixin(handleThem()); 58 } 59 60 if (!columns || !columns.length) 61 { 62 return ""; 63 } 64 65 { 66 mixin HandleFields!(T, q{{ 67 enum hasId = hasUDA!({{fullName}}, DbId); 68 69 static if (hasId) 70 { 71 idName = "{{fieldName}}"; 72 idParams = "params[%s] = model.{{fieldName}};".format(columns.length); 73 } 74 }}); 75 mixin(handleThem()); 76 77 if (!idName) 78 { 79 return ""; 80 } 81 } 82 83 { 84 mixin HandleFields!(T, q{{ 85 enum hasNoMap = hasUDA!({{fullName}}, DbNoMap); 86 enum hasId = hasUDA!({{fullName}}, DbId); 87 88 static if (!hasNoMap && !hasId) 89 { 90 enum hasEnum = hasUDA!({{fullName}}, DbEnum); 91 enum hasTimestamp = hasUDA!({{fullName}}, DbTimestamp); 92 93 static if (hasEnum) 94 { 95 paramsUpdates ~= "params[index++] = cast(string)model.{{fieldName}};"; 96 } 97 else static if (hasTimestamp) 98 { 99 paramsUpdates ~= ` 100 model.timestamp = Clock.currTime().asDateTime(); 101 params[index++] = model.timestamp; 102 `; 103 } 104 else static if (is(typeof({{fullName}}) == bool)) 105 { 106 paramsUpdates ~= "params[index++] = cast(ubyte)model.{{fieldName}};"; 107 } 108 else 109 { 110 paramsUpdates ~= "params[index++] = model.{{fieldName}};"; 111 } 112 } 113 }}); 114 mixin(handleThem()); 115 } 116 117 if (!paramsUpdates || !paramsUpdates.length) 118 { 119 return ""; 120 } 121 122 return s.format(T.table, columns.join(","), idName, (columns.length + 1), paramsUpdates.join("\r\n"), idParams); 123 }