Exemplo n.º 1
0
 private void ValidateParameter()
 {
     if (this.userSpecifiedType && (OleDbType.Empty == OleDbType))
     {
         throw ODB.UninitializedParameters(this.parent.IndexOf(this), ParameterName, OleDbType);
     }
     else if ((0 == GetParameterSize()) && (0 != (ParameterDirection.Output & Direction)))
     {
         throw ADP.UninitializedParameterSize(this.parent.IndexOf(this), ParameterName, NativeDBType.dataType, Size);
     }
     Debug.Assert(0 <= Size, "unexpected parameter size");
 }
Exemplo n.º 2
0
        // goal: call virtual property getters only once per parameter
        internal bool BindParameter(int index, Bindings bindings)
        {
            int    changeID = _changeID;
            object value    = Value;

            NativeDBType dbtype = GetBindType(value);

            if (OleDbType.Empty == dbtype.enumOleDbType)
            {
                throw ODB.UninitializedParameters(index, dbtype.enumOleDbType);
            }
            _coerceMetaType = dbtype;
            value           = CoerceValue(value, dbtype);
            CoercedValue    = value;

            ParameterDirection direction = Direction;

            byte precision;

            if (ShouldSerializePrecision())
            {
                precision = PrecisionInternal;
            }
            else
            {
                precision = ValuePrecision(value);
            }
            if (0 == precision)
            {
                precision = dbtype.maxpre;
            }

            byte scale;

            if (ShouldSerializeScale())
            {
                scale = ScaleInternal;
            }
            else
            {
                scale = ValueScale(value);
            }

            int wtype = dbtype.wType;
            int bytecount, size;

            if (dbtype.islong)   // long data (image, text, ntext)
            {
                bytecount = ADP.PtrSize;
                if (ShouldSerializeSize())
                {
                    size = Size;
                }
                else
                {
                    if (NativeDBType.STR == dbtype.dbType)
                    {
                        size = Int32.MaxValue; // WebData 98940
                    }
                    else if (NativeDBType.WSTR == dbtype.dbType)
                    {
                        size = Int32.MaxValue / 2;
                    }
                    else
                    {
                        size = Int32.MaxValue;
                    }
                }
                wtype |= NativeDBType.BYREF;
            }
            else if (dbtype.IsVariableLength)   // variable length data (varbinary, varchar, nvarchar)
            {
                if (!ShouldSerializeSize() && ADP.IsDirection(this, ParameterDirection.Output))
                {
                    throw ADP.UninitializedParameterSize(index, _coerceMetaType.dataType);
                }

                bool computedSize;
                if (ShouldSerializeSize())
                {
                    size         = Size;
                    computedSize = false;
                }
                else
                {
                    size         = ValueSize(value);
                    computedSize = true;
                }
                if (0 < size)
                {
                    if (NativeDBType.WSTR == dbtype.wType)
                    {
                        // maximum 0x3FFFFFFE characters, computed this way to avoid overflow exception
                        bytecount = Math.Min(size, 0x3FFFFFFE) * 2 + 2;
                    }
                    else
                    {
                        Debug.Assert(NativeDBType.STR != dbtype.wType, "should have ANSI binding, describing is okay");
                        bytecount = size;
                    }

                    if (computedSize)
                    {
                        if (NativeDBType.STR == dbtype.dbType)   // WebData 98140
                        // maximum 0x7ffffffe characters, computed this way to avoid overflow exception
                        {
                            size = Math.Min(size, 0x3FFFFFFE) * 2;
                        }
                    }

                    if (ODB.LargeDataSize < bytecount)
                    {
                        bytecount = ADP.PtrSize;
                        wtype    |= NativeDBType.BYREF;
                    }
                }
                else if (0 == size)
                {
                    if (NativeDBType.WSTR == wtype)   // allow space for null termination character
                    {
                        bytecount = 2;
                        // 0 == size, okay for (STR == dbType)
                    }
                    else
                    {
                        Debug.Assert(NativeDBType.STR != dbtype.wType, "should have ANSI binding, describing is okay");
                        bytecount = 0;
                    }
                }
                else if (-1 == size)
                {
                    bytecount = ADP.PtrSize;
                    wtype    |= NativeDBType.BYREF;
                }
                else
                {
                    throw ADP.InvalidSizeValue(size);
                }
            }
            else   // fixed length data
            {
                bytecount = dbtype.fixlen;
                size      = bytecount;
            }
            bindings.CurrentIndex = index;

            // tagDBPARAMBINDINFO info for SetParameterInfo
            bindings.DataSourceType = dbtype.dbString.DangerousGetHandle(); // NOTE: This is a constant and isn't exposed publicly, so there really isn't a potential for Handle Recycling.
            bindings.Name           = ADP.PtrZero;
            bindings.ParamSize      = new IntPtr(size);
            bindings.Flags          = GetBindFlags(direction);
            //bindings.Precision    = precision;
            //bindings.Scale        = scale;

            // tagDBBINDING info for CreateAccessor
            bindings.Ordinal   = (IntPtr)(index + 1);
            bindings.Part      = dbtype.dbPart;
            bindings.ParamIO   = GetBindDirection(direction);
            bindings.Precision = precision;
            bindings.Scale     = scale;
            bindings.DbType    = wtype;
            bindings.MaxLen    = bytecount;    // also increments databuffer size (uses DbType)
            //bindings.ValueOffset  = bindings.DataBufferSize; // set via MaxLen
            //bindings.LengthOffset = i * sizeof_int64;
            //bindings.StatusOffset = i * sizeof_int64 + sizeof_int32;
            //bindings.TypeInfoPtr  = 0;
            //bindings.ObjectPtr    = 0;
            //bindings.BindExtPtr   = 0;
            //bindings.MemOwner     = /*DBMEMOWNER_CLIENTOWNED*/0;
            //bindings.Flags        = 0;

            //bindings.ParameterChangeID = changeID; // bind until something changes
            Debug.Assert(_changeID == changeID, "parameter has unexpectedly changed");

            if (Bid.AdvancedOn)
            {
                Bid.Trace("<oledb.struct.tagDBPARAMBINDINFO|INFO|ADV> index=%d, parameterName='%ls'\n", index, ParameterName); //, bindings.BindInfo[index]);
                Bid.Trace("<oledb.struct.tagDBBINDING|INFO|ADV>\n");                                                           //, bindings.DBBinding[index]);
            }
            return(IsParameterComputed());
        }
        internal bool BindParameter(int index, Bindings bindings)
        {
            int          size;
            int          ptrSize;
            byte         precisionInternal;
            byte         scaleInternal;
            object       obj2     = this.Value;
            NativeDBType bindType = this.GetBindType(obj2);

            if (bindType.enumOleDbType == System.Data.OleDb.OleDbType.Empty)
            {
                throw ODB.UninitializedParameters(index, bindType.enumOleDbType);
            }
            this._coerceMetaType = bindType;
            obj2 = CoerceValue(obj2, bindType);
            this.CoercedValue = obj2;
            ParameterDirection direction = this.Direction;

            if (this.ShouldSerializePrecision())
            {
                precisionInternal = this.PrecisionInternal;
            }
            else
            {
                precisionInternal = this.ValuePrecision(obj2);
            }
            if (precisionInternal == 0)
            {
                precisionInternal = bindType.maxpre;
            }
            if (this.ShouldSerializeScale())
            {
                scaleInternal = this.ScaleInternal;
            }
            else
            {
                scaleInternal = this.ValueScale(obj2);
            }
            int wType = bindType.wType;

            if (bindType.islong)
            {
                ptrSize = ADP.PtrSize;
                if (this.ShouldSerializeSize())
                {
                    size = this.Size;
                }
                else if (0x81 == bindType.dbType)
                {
                    size = 0x7fffffff;
                }
                else if (130 == bindType.dbType)
                {
                    size = 0x3fffffff;
                }
                else
                {
                    size = 0x7fffffff;
                }
                wType |= 0x4000;
            }
            else if (bindType.IsVariableLength)
            {
                bool flag;
                if (!this.ShouldSerializeSize() && ADP.IsDirection(this, ParameterDirection.Output))
                {
                    throw ADP.UninitializedParameterSize(index, this._coerceMetaType.dataType);
                }
                if (this.ShouldSerializeSize())
                {
                    size = this.Size;
                    flag = false;
                }
                else
                {
                    size = this.ValueSize(obj2);
                    flag = true;
                }
                if (0 >= size)
                {
                    if (size != 0)
                    {
                        if (-1 != size)
                        {
                            throw ADP.InvalidSizeValue(size);
                        }
                        ptrSize = ADP.PtrSize;
                        wType  |= 0x4000;
                    }
                    else if (130 == wType)
                    {
                        ptrSize = 2;
                    }
                    else
                    {
                        ptrSize = 0;
                    }
                }
                else
                {
                    if (130 == bindType.wType)
                    {
                        ptrSize = (Math.Min(size, 0x3ffffffe) * 2) + 2;
                    }
                    else
                    {
                        ptrSize = size;
                    }
                    if (flag && (0x81 == bindType.dbType))
                    {
                        size = Math.Min(size, 0x3ffffffe) * 2;
                    }
                    if (0x2000 < ptrSize)
                    {
                        ptrSize = ADP.PtrSize;
                        wType  |= 0x4000;
                    }
                }
            }
            else
            {
                ptrSize = bindType.fixlen;
                size    = ptrSize;
            }
            bindings.CurrentIndex   = index;
            bindings.DataSourceType = bindType.dbString.DangerousGetHandle();
            bindings.Name           = ADP.PtrZero;
            bindings.ParamSize      = new IntPtr(size);
            bindings.Flags          = GetBindFlags(direction);
            bindings.Ordinal        = (IntPtr)(index + 1);
            bindings.Part           = bindType.dbPart;
            bindings.ParamIO        = GetBindDirection(direction);
            bindings.Precision      = precisionInternal;
            bindings.Scale          = scaleInternal;
            bindings.DbType         = wType;
            bindings.MaxLen         = ptrSize;
            if (Bid.AdvancedOn)
            {
                Bid.Trace("<oledb.struct.tagDBPARAMBINDINFO|INFO|ADV> index=%d, parameterName='%ls'\n", index, this.ParameterName);
                Bid.Trace("<oledb.struct.tagDBBINDING|INFO|ADV>\n");
            }
            return(this.IsParameterComputed());
        }