public IClickHouseColumnWriter CreateColumnWriter <T>(string columnName, IReadOnlyList <T> rows, ClickHouseColumnSettings?columnSettings) { if (_elementTypeInfo == null) { throw new ClickHouseException(ClickHouseErrorCodes.TypeNotFullySpecified, $"The type \"{ComplexTypeName}\" is not fully specified."); } Type?elementType = null; foreach (var genericItf in typeof(T).GetInterfaces().Where(itf => itf.IsGenericType)) { if (genericItf.GetGenericTypeDefinition() != typeof(IReadOnlyList <>)) { continue; } if (elementType == null) { elementType = genericItf.GetGenericArguments()[0]; } else { var elementTypeCandidate = genericItf.GetGenericArguments()[0]; if (elementType.IsAssignableFrom(elementTypeCandidate)) { elementType = elementTypeCandidate; } else if (!elementTypeCandidate.IsAssignableFrom(elementType)) { throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, $"Can't detect a type of the array's element. Candidates are: \"{elementType}\" and \"{elementTypeCandidate}\"."); } } } if (elementType == null) { throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, $"Can't detect a type of the array's element. The type \"{typeof(T)}\" doesn't implement \"{typeof(IReadOnlyList<>)}\"."); } var dispatcher = new ArrayColumnWriterDispatcher(columnName, ComplexTypeName, rows, columnSettings, _elementTypeInfo); return(TypeDispatcher.Dispatch(elementType, dispatcher)); }
public IClickHouseColumnWriter CreateColumnWriter <T>(string columnName, IReadOnlyList <T> rows, ClickHouseColumnSettings?columnSettings) { if (_elementTypeInfo == null) { throw new ClickHouseException(ClickHouseErrorCodes.TypeNotFullySpecified, $"The type \"{ComplexTypeName}\" is not fully specified."); } var rowType = typeof(T); Type?elementType = null; if (rowType.IsArray) { var rank = rowType.GetArrayRank(); if (rank > 1) { elementType = rowType.GetElementType() !; Debug.Assert(elementType != null); var listAdapterInfo = MultiDimensionalArrayReadOnlyListAdapter.Dispatch(elementType, rowType.GetArrayRank()); var mdaDispatcher = new MultiDimensionalArrayColumnWriterDispatcher( columnName, (IReadOnlyList <Array>)rows, columnSettings, _elementTypeInfo, listAdapterInfo.createList); return(TypeDispatcher.Dispatch(listAdapterInfo.listElementType, mdaDispatcher)); } } foreach (var genericItf in rowType.GetInterfaces().Where(itf => itf.IsGenericType)) { if (genericItf.GetGenericTypeDefinition() != typeof(IReadOnlyList <>)) { continue; } if (elementType == null) { elementType = genericItf.GetGenericArguments()[0]; } else { var elementTypeCandidate = genericItf.GetGenericArguments()[0]; if (elementType.IsAssignableFrom(elementTypeCandidate)) { elementType = elementTypeCandidate; } else if (!elementTypeCandidate.IsAssignableFrom(elementType)) { throw new ClickHouseException( ClickHouseErrorCodes.TypeNotSupported, $"Can't detect a type of the array's element. Candidates are: \"{elementType}\" and \"{elementTypeCandidate}\"."); } } } ArrayColumnWriterDispatcherBase dispatcher; if (elementType == null) { var rowGenericTypeDef = rowType.GetGenericTypeDefinition(); if (rowGenericTypeDef == typeof(ReadOnlyMemory <>)) { elementType = rowType.GetGenericArguments()[0] !; dispatcher = new ReadOnlyColumnWriterDispatcher(columnName, rows, columnSettings, _elementTypeInfo); } else if (rowGenericTypeDef == typeof(Memory <>)) { elementType = rowType.GetGenericArguments()[0] !; dispatcher = new MemoryColumnWriterDispatcher(columnName, rows, columnSettings, _elementTypeInfo); } else { throw new ClickHouseException( ClickHouseErrorCodes.TypeNotSupported, $"Can't detect a type of the array's element. The type \"{typeof(T)}\" doesn't implement \"{typeof(IReadOnlyList<>)}\"."); } } else { dispatcher = new ArrayColumnWriterDispatcher(columnName, rows, columnSettings, _elementTypeInfo); } try { return(TypeDispatcher.Dispatch(elementType, dispatcher)); } catch (ClickHouseException ex) when(ex.ErrorCode == ClickHouseErrorCodes.TypeNotSupported) { throw new ClickHouseException(ex.ErrorCode, $"The type \"{rowType}\" can't be converted to the ClickHouse type \"{ComplexTypeName}\". See the inner exception for details.", ex); } }