public MetadataOracleObject(MetadataOracleNetTypeDefinition oracleNetTypeDefinition, MetadataOracleCommon common) { OracleTypeNetMetadata = oracleNetTypeDefinition ?? throw new ArgumentNullException(nameof(oracleNetTypeDefinition)); _Common = common ?? throw new ArgumentNullException(nameof(common)); Type = typeof(T); ConstructorString = GenerateConstructor(OracleTypeNetMetadata.UDTInfo.FullObjectName, OracleTypeNetMetadata.Properties.ToArray()); }
private string GetRefCursorObjectQuery(int startNumber, string fieldName, MetadataOracleNetTypeDefinition oracleTypeNetMetadata) { var query = new StringBuilder($"open :{startNumber} for select "); query.AppendLine(QueryBuilder(oracleTypeNetMetadata, $"value({fieldName})", isRoot: true)); query.Append(" from dual;"); return(query.ToString()); }
/// <see cref="MetadataOracleObject{T}.MetadataOracleObject(MetadataOracleNetTypeDefinition, MetadataOracleCommon)" private async Task <object> RegisterAsync(Type type, DbConnection con, OracleUdtInfo udtInfo) { var metadataGenericType = typeof(MetadataOracleObject <>).MakeGenericType(type); var typeMetadata = await GetOrCreateOracleTypeMetadataAsync(con, udtInfo); var(_, props, fuzzyMatch) = Cache.PresetGetValueOrDefault(type); var typedef = new MetadataOracleNetTypeDefinition(Cache, type.IsCollection() ? type.GetCollectionUnderType() : type, typeMetadata, props, fuzzyMatch); var metadata = metadataGenericType.CreateInstance(typedef, new MetadataOracleCommon()); Cache.SaveMetadata(type.FullName, metadata as MetadataBase); return(metadata); }
/// <see cref="MetadataOracleObject{T}.MetadataOracleObject(MetadataOracleNetTypeDefinition, MetadataOracleCommon)" private object Register(Type type, DbConnection con, OracleUdtInfo udtInfo) { var metadataGenericType = typeof(MetadataOracleObject <>).MakeGenericType(type); var typeMetadata = GetOrCreateOracleTypeMetadata(con, udtInfo); var(_, props, fuzzyMatch) = Cache.PresetGetValueOrDefault(type); var typedef = new MetadataOracleNetTypeDefinition(Cache, type.IsCollection() ? type.GetCollectionUnderType() : type, typeMetadata, props, fuzzyMatch); var metadata = metadataGenericType.CreateInstance(typedef, new MetadataOracleCommon()); Logger?.LogDebug("Saving cache for the type {typeName}", type.FullName); Cache.SaveMetadata(type.FullName, metadata as MetadataBase); return(metadata); }
private IEnumerable <OracleParameter> ProcessOracleParameter(object value, MetadataOracleNetTypeDefinition metadata, int startNumber, out int newNumber) { var propertiesParameters = new List <OracleParameter>(); foreach (var prop in metadata.Properties.Where(c => c.PropertyMetadata != null).OrderBy(c => c.Order)) { if (value != null && prop.NETProperty.GetValue(value) != null) { if (prop.NETProperty.PropertyType.IsCollection()) { propertiesParameters.AddRange(ProcessCollectionParameters(prop.NETProperty.GetValue(value) as IEnumerable, prop.PropertyMetadata, startNumber, out startNumber)); } else { propertiesParameters.AddRange(ProcessOracleParameter(prop.NETProperty.GetValue(value), prop.PropertyMetadata, startNumber, out startNumber)); } } } foreach (var prop in metadata.Properties.Where(c => c.NETProperty != null && c.PropertyMetadata is null).OrderBy(c => c.Order)) { if (value != null && prop.NETProperty.GetValue(value) != null) { propertiesParameters.Add( _Common.GetOracleParameter( type: prop.NETProperty.PropertyType, direction: ParameterDirection.Input, name: $":{startNumber++}", value: prop.NETProperty.GetValue(value) )); } } newNumber = startNumber; return(propertiesParameters); }
private void BuildQueryConstructor(StringBuilder baseString, Type type, object value, string name, ref int startNumber, MetadataOracleNetTypeDefinition metadata, string constructor) { if (type.IsCollection()) { if (value != null) { foreach (var v in value as IEnumerable) { var baseConstructor = BuildConstructor(baseString, v, name, metadata, ref startNumber, constructor); baseString.AppendLine($"{name}.extend;"); baseString.AppendLine($"{name}({name}.last) := {baseConstructor}"); } } } else { var baseConstructor = BuildConstructor(baseString, value, name, metadata, ref startNumber, constructor); baseString.AppendLine($"{name} := {baseConstructor}"); } }
private string BuildConstructor(StringBuilder baseString, object value, string parameterName, MetadataOracleNetTypeDefinition metadata, ref int startNumber, string constructor) { var workedTypes = new Dictionary <string, string>(); int dependenciesCounter = 0; foreach (var prop in metadata.Properties.Where(c => c.PropertyMetadata != null).OrderBy(c => c.Order)) { var workedName = parameterName + "_" + dependenciesCounter++; var subConstructor = GenerateConstructor(prop.PropertyMetadata.UDTInfo.FullObjectName, prop.PropertyMetadata.Properties.ToArray()); BuildQueryConstructor(baseString, prop.NETProperty.PropertyType, value != null ? prop.NETProperty.GetValue(value) : null, workedName, ref startNumber, prop.PropertyMetadata, subConstructor); workedTypes.Add(prop.Name, workedName); } foreach (var prop in metadata.Properties.OrderBy(c => c.Order)) { if (prop.NETProperty != null) { if (prop.PropertyMetadata != null) { workedTypes.TryGetValue(prop.Name, out var subtype); constructor = regex.Replace(constructor, subtype, 1); } else if (value != null && prop.NETProperty.GetValue(value) != null) { constructor = regex.Replace(constructor, $":{startNumber++}", 1); } else { constructor = regex.Replace(constructor, "null", 1); } } else { constructor = regex.Replace(constructor, "null", 1); } } return(constructor); }
private string GetDeclareLine(Type type, string parameterName, OracleUdtInfo udtInfo, MetadataOracleNetTypeDefinition metadata) { var dependenciesCounter = 0; var declareLine = new StringBuilder(); foreach (var prop in metadata.Properties.Where(c => c.PropertyMetadata != null).OrderBy(c => c.Order)) { var subName = parameterName + "_" + dependenciesCounter++; declareLine.Append(GetDeclareLine(prop.NETProperty.PropertyType, subName, prop.PropertyMetadata.UDTInfo, prop.PropertyMetadata)); } if (type.IsCollection()) { declareLine.AppendLine($"{parameterName} {udtInfo.FullCollectionName} := {udtInfo.FullCollectionName}();"); } else { declareLine.AppendLine($"{parameterName} {udtInfo.FullObjectName};"); } return(declareLine.ToString()); }
private dynamic ReadObjectInstance(Type type, IOracleDataReaderWrapper reader, MetadataOracleNetTypeDefinition metadata, ref int count) { var instance = type.CreateInstance(); int nullCounter = 0; foreach (var prop in metadata.Properties.Where(c => c.NETProperty != null).OrderBy(c => c.Order)) { var subType = prop.NETProperty.PropertyType; var oracleValue = reader.GetOracleValue(count++); dynamic subInstance; if (prop.PropertyMetadata != null) { //TODO Find a way to cast the read value without creating an instance twice. subInstance = subType.CreateInstance(); subInstance = _Common.GetValueFromOracleXML(subType, oracleValue as OracleXmlType); } else { subInstance = _Common.ConvertOracleParameterToBaseType(subType, oracleValue); } prop.NETProperty.SetValue(instance, subInstance); if (subInstance is null) { nullCounter++; } } return(instance); }
private string QueryBuilder(MetadataOracleNetTypeDefinition metadata, string tableName, int level = 0, bool isRoot = false) { var select = new StringBuilder(); var first = true; foreach (var prop in metadata.Properties.Where(c => c.NETProperty != null).OrderBy(c => c.Order)) { if (first) { first = false; } else { select.AppendLine(","); } var newTable = $"{tableName}.{prop.Name}"; if (prop.PropertyMetadata != null) { if (prop.NETProperty.PropertyType.IsCollection()) { var futureLevel = level + 1; var levelStr = $"d{futureLevel}"; select.Append($"(select xmlelement( \"{prop.NETProperty.Name}\","); select.Append($" xmlagg( xmlconcat( xmlelement( \"{prop.NETProperty.Name}\", "); select.Append(QueryBuilder(prop.PropertyMetadata, levelStr, futureLevel)); select.Append($") ) ) ) from table({tableName}.{prop.Name}) {levelStr})"); if (isRoot) { select.Append($" {prop.Name}"); } } else { select.Append($"(select xmlelement( \"{prop.NETProperty.Name}\", xmlconcat( "); select.Append(QueryBuilder(prop.PropertyMetadata, newTable)); select.Append(") ) from dual)"); if (isRoot) { select.Append($" {prop.NETProperty.Name}"); } } } else { if (isRoot) { select.Append($"{tableName}.{prop.Name} {prop.NETProperty.Name}"); } else { select.Append($"XmlElement(\"{prop.NETProperty.Name}\", {tableName}.{prop.Name})"); } } } if (first) { //TODO Log error message because it couldn't process any properties select.Append("1 dummy"); } return(select.ToString()); }
private IEnumerable <OracleParameter> ProcessCollectionParameters(IEnumerable value, MetadataOracleNetTypeDefinition metadata, int startNumber, out int lastNumber) { var rowsParameters = new List <OracleParameter>(); if (value != null) { foreach (var temp in value) { rowsParameters.AddRange(ProcessOracleParameter(temp, metadata, startNumber, out startNumber)); } } lastNumber = startNumber; return(rowsParameters); }