Ejemplo n.º 1
0
        public Action <MappingSchema, NpgsqlBinaryImporter, ColumnDescriptor[], TEntity> CreateBinaryImportRowWriter <TEntity>(
            PostgreSQLDataProvider provider,
            BasicSqlBuilder sqlBuilder,
            ColumnDescriptor[] columns,
            MappingSchema mappingSchema)
        {
            var generator = new ExpressionGenerator(_typeMapper);

            var pMapping  = Expression.Parameter(typeof(MappingSchema));
            var pWriterIn = Expression.Parameter(typeof(NpgsqlBinaryImporter));
            var pColumns  = Expression.Parameter(typeof(ColumnDescriptor[]));
            var pEntity   = Expression.Parameter(typeof(TEntity));

            var pWriter = generator.AddVariable(Expression.Parameter(_npgsqlBinaryImporterType));

            generator.Assign(pWriter, Expression.Convert(ExpressionHelper.Property(pWriterIn, nameof(TypeWrapper.instance_)), _npgsqlBinaryImporterType));

            generator.AddExpression(generator.MapAction((NpgsqlBinaryImporter importer) => importer.StartRow(), pWriter));

            for (var i = 0; i < columns.Length; i++)
            {
                var npgsqlType = provider.GetNativeType(columns[i].DbType, true);
                if (npgsqlType == null)
                {
                    var columnType = columns[i].DataType != DataType.Undefined ? new SqlDataType(columns[i]) : null;

                    if (columnType == null || columnType.Type.DataType == DataType.Undefined)
                    {
                        columnType = mappingSchema.GetDataType(columns[i].StorageType);
                    }

                    var sb = new StringBuilder();
                    sqlBuilder.BuildTypeName(sb, columnType);
                    npgsqlType = provider.GetNativeType(sb.ToString(), true);
                }

                if (npgsqlType == null)
                {
                    throw new LinqToDBException($"Cannot guess PostgreSQL type for column {columns[i].ColumnName}. Specify type explicitly in column mapping.");
                }

                // don't use WriteNull because Write already handle both null and DBNull values properly
                // also use object as type parameter, as it is not important for npgsql now
                generator.AddExpression(
                    Expression.Call(
                        pWriter,
                        "Write",
                        new[] { typeof(object) },
                        //columns[idx].GetValue(mappingSchema, entity)
                        Expression.Call(Expression.ArrayIndex(pColumns, Expression.Constant(i)), "GetValue", Array <Type> .Empty, pMapping, pEntity),
                        Expression.Convert(Expression.Constant(npgsqlType.Value), _dbTypeType)));
            }

            var ex = Expression.Lambda <Action <MappingSchema, NpgsqlBinaryImporter, ColumnDescriptor[], TEntity> >(
                generator.Build(),
                pMapping, pWriterIn, pColumns, pEntity);

            return(ex.Compile());
        }
        public void Setup()
        {
            var typeMapper = new TypeMapper();

            typeMapper.RegisterTypeWrapper <Wrapped.NpgsqlBinaryImporter>(typeof(Original.NpgsqlBinaryImporter));
            typeMapper.RegisterTypeWrapper <Wrapped.NpgsqlDbType>(typeof(Original.NpgsqlDbType));

            typeMapper.FinalizeMappings();

            _wrappedImporter = typeMapper.Wrap <Wrapped.NpgsqlBinaryImporter>(_originalImporter);

            var ed = MappingSchema.GetEntityDescriptor(typeof(TestEntity));

            _columns = ed.Columns.ToArray();

            var generator = new ExpressionGenerator(typeMapper);

            var pMapping  = Expression.Parameter(typeof(MappingSchema));
            var pWriterIn = Expression.Parameter(typeof(Wrapped.NpgsqlBinaryImporter));
            var pColumns  = Expression.Parameter(typeof(ColumnDescriptor[]));
            var pEntity   = Expression.Parameter(typeof(TestEntity));
            var pWriter   = generator.AddVariable(Expression.Parameter(typeof(Original.NpgsqlBinaryImporter)));

            generator.Assign(pWriter, Expression.Convert(Expression.PropertyOrField(pWriterIn, "instance_"), typeof(Original.NpgsqlBinaryImporter)));
            generator.AddExpression(generator.MapAction((Wrapped.NpgsqlBinaryImporter importer) => importer.StartRow(), pWriter));

            for (var i = 0; i < _columns.Length; i++)
            {
                generator.AddExpression(
                    Expression.Call(
                        pWriter,
                        "Write",
                        new[] { typeof(object) },
                        Expression.Call(Expression.ArrayIndex(pColumns, Expression.Constant(i)), "GetValue", Array <Type> .Empty, pEntity),
                        Expression.Convert(Expression.Constant(Wrapped.NpgsqlDbType.Test), typeof(Original.NpgsqlDbType))));
            }

            _rowWriter = Expression.Lambda <Action <MappingSchema, Wrapped.NpgsqlBinaryImporter, ColumnDescriptor[], TestEntity> >(
                generator.Build(),
                pMapping, pWriterIn, pColumns, pEntity)
                         .Compile();
        }