1 /* 2 * Entity - Entity is an object-relational mapping tool for the D programming language. Referring to the design idea of JPA. 3 * 4 * Copyright (C) 2015-2018 Shanghai Putao Technology Co., Ltd 5 * 6 * Developer: HuntLabs.cn 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.entity.EntityFieldOneToOne; 13 14 import hunt.entity; 15 import hunt.Exceptions; 16 import hunt.logging; 17 18 import std.range; 19 import std.string; 20 import std.variant; 21 22 class EntityFieldOneToOne(T : Object , F : Object) : EntityFieldObject!(T,F) { 23 24 private OneToOne _mode; 25 private string _primaryKey; 26 private bool _isMappedBy; 27 28 this(EntityManager manager, string fieldName, string primaryKey, string columnOrjoin, 29 string tableName, T fieldValue, OneToOne mode, F owner) { 30 string mappedBy = mode.mappedBy; 31 32 _mode = mode; 33 _enableJoin = _mode.fetch == FetchType.EAGER; 34 _isMappedBy = !mappedBy.empty(); 35 36 super(manager, fieldName, 37 _isMappedBy ? "" : columnOrjoin, 38 tableName, 39 _isMappedBy ? null : fieldValue , 40 owner); 41 42 _primaryKey = primaryKey; 43 if (_isMappedBy) { 44 EntityFieldInfo fieldInfo = _entityInfo.getSingleField(mappedBy); 45 if(fieldInfo is null) { 46 string msg = format("Can't get the field info for [%s] in %s", mappedBy, T.stringof); 47 warningf(msg); 48 throw new EntityException(msg); 49 // _joinColumn = columnOrjoin; 50 } else { 51 _joinColumn = fieldInfo.getJoinColumn(); 52 } 53 } 54 else 55 { 56 _joinColumn = columnOrjoin; 57 _columnFieldData = Variant(_entityInfo.getPrimaryValue()); 58 59 // _columnFieldData = new ColumnFieldData(); 60 // _columnFieldData.valueType = typeof(_entityInfo.getPrimaryValue()).stringof; 61 // // if (_columnFieldData.valueType == "string" && manager !is null) 62 // // _columnFieldData.value = /*manager.getDatabase().escapeLiteral*/(_entityInfo.getPrimaryValue().to!string); 63 // // else 64 // // _columnFieldData.value = _entityInfo.getPrimaryValue().to!string; 65 // _columnFieldData.value = new hunt.Nullable.Nullable!(typeof(_entityInfo.getPrimaryValue()))(_entityInfo.getPrimaryValue()); 66 67 _foreignKeyData = new ForeignKeyData(); 68 _foreignKeyData.columnName = columnOrjoin; 69 _foreignKeyData.tableName = _entityInfo.getTableName(); 70 _foreignKeyData.primaryKey = _entityInfo.getPrimaryKeyString(); 71 72 } 73 74 initJoinData(tableName); 75 } 76 77 override string getSelectColumn() { 78 if (_isMappedBy) 79 return ""; 80 else 81 return super.getSelectColumn(); 82 } 83 84 private void initJoinData(string tableName) { 85 _joinSqlData = new JoinSqlBuild(); 86 _joinSqlData.tableName = _entityInfo.getTableName(); 87 if (_isMappedBy) { 88 _joinSqlData.joinWhere = tableName ~ "." ~ _primaryKey ~ " = " ~ _entityInfo.getTableName() ~ "." ~ _joinColumn; 89 } 90 else { 91 _joinSqlData.joinWhere = tableName ~ "." ~ _joinColumn ~ " = " ~ _entityInfo.getTableName() ~ "." ~ _entityInfo.getPrimaryKeyString(); 92 } 93 _joinSqlData.joinType = JoinType.LEFT; 94 foreach(value; _entityInfo.getFields()) { 95 _joinSqlData.columnNames ~= value.getSelectColumn(); 96 } 97 // logDebug("one to one join sql : %s ".format(_joinSqlData)); 98 99 } 100 101 T deSerialize(Row row, F owner) { 102 version(HUNT_ENTITY_DEBUG) { 103 infof("Deserializing %s based on a row, the owner %s null", 104 T.stringof, owner is null ? "is" : "is not"); 105 } 106 107 if (_mode.fetch == FetchType.LAZY) 108 return null; 109 long count = -1; 110 return _entityInfo.deSerialize([row], count, 0, owner); 111 } 112 113 override LazyData getLazyData(Row row) { 114 LazyData ret; 115 116 string primaryKeyName = _entityInfo.getPrimaryKeyString(); 117 if (_isMappedBy) { 118 119 string name = EntityExpression.getColumnAsName(primaryKeyName, getTableName()); 120 Variant v = row.getValue(name); 121 if(!v.hasValue()) { 122 version(HUNT_ENTITY_DEBUG) warningf("Can't find value for %s", name); 123 return null; 124 } 125 126 string value = v.toString(); 127 version(HUNT_ENTITY_DEBUG) tracef("A column: %s = %s", name, value); 128 ret = new LazyData(_mode.mappedBy, value); 129 } else { 130 string name = EntityExpression.getColumnAsName(_joinColumn, getTableName()); 131 Variant v = row.getValue(name); 132 if(!v.hasValue()) { 133 version(HUNT_ENTITY_DEBUG) warningf("Can't find value for %s", name); 134 return null; 135 } 136 137 string value = v.toString(); 138 version(HUNT_ENTITY_DEBUG) tracef("A column: %s = %s", name, value); 139 ret = new LazyData(primaryKeyName, value); 140 } 141 return ret; 142 } 143 144 void setMode(OneToOne mode) { 145 _mode = mode; 146 _enableJoin = _mode.fetch == FetchType.EAGER; 147 } 148 149 override FetchType fetchType() { 150 return _mode.fetch; 151 } 152 }