1 /** 2 Contains several attributes used in SQL databases. 3 */ 4 module ezdb.entity; 5 6 import std.traits; 7 import std.typecons; 8 9 /** 10 Defines the primary key of an entity. 11 */ 12 enum primaryKey; // @suppress(dscanner.style.phobos_naming_convention) 13 14 /** 15 Aliases to the type of the primary key of an entity. 16 */ 17 template PrimaryKeyType(Type) 18 { 19 alias PrimaryKeyType = typeof(PrimaryKeySymbol!Type); 20 } 21 22 /** 23 The `PrimaryKeyType` template returns the type of the primary key. 24 */ 25 @("PrimaryKeyType returns correct primary key type") 26 @safe @nogc pure unittest 27 { 28 static struct MyEntity 29 { 30 @primaryKey 31 int a; 32 33 int b; 34 } 35 36 assert(is(PrimaryKeyType!MyEntity == int)); 37 } 38 39 /** 40 Aliases to the symbol that is the primary key of an entity. 41 */ 42 template PrimaryKeySymbol(Type) 43 { 44 static if (getSymbolsByUDA!(Type, primaryKey).length == 1) 45 { 46 alias PrimaryKeySymbol = getSymbolsByUDA!(Type, primaryKey)[0]; 47 } 48 else 49 { 50 static assert(false, "An entity should have exactly one @primaryKey"); 51 } 52 } 53 54 @("Cannot compile PrimaryKey with two primary keys") 55 @safe @nogc pure unittest 56 { 57 static struct MyEntity 58 { 59 @primaryKey 60 int id; 61 62 @primaryKey 63 int secondId; 64 } 65 66 assert(!__traits(compiles, PrimaryKeySymbol!MyEntity)); 67 } 68 69 @("Cannot compile PrimaryKey with no primary keys") 70 @safe @nogc pure unittest 71 { 72 static struct MyEntity 73 { 74 } 75 76 assert(!__traits(compiles, PrimaryKeySymbol!MyEntity)); 77 } 78 79 /** 80 Gets a reference to the primary key of an entity. 81 */ 82 ref auto getPrimaryKey(Entity)(Entity entity) // @suppress(dscanner.suspicious.unused_parameter) 83 { 84 return __traits(getMember, entity, getSymbolsByUDA!(typeof(entity), primaryKey)[0].stringof); 85 } 86 87 /** 88 Sets the primary key of an entity. 89 */ 90 void setPrimaryKey(Entity, Id = PrimaryKeyType!Entity)(ref Entity entity, Id key) // @suppress(dscanner.suspicious.unused_parameter) 91 { 92 __traits(getMember, entity, getSymbolsByUDA!(typeof(entity), primaryKey)[0].stringof) = key; 93 }