Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        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);
            }
        }