internal OleDbDataReader(OleDbConnection connection, OleDbCommand command, int depth, CommandBehavior commandBehavior) { this._connection = connection; this._command = command; this._commandBehavior = commandBehavior; if ((command != null) && (this._depth == 0)) { this._parameterBindings = command.TakeBindingOwnerShip(); } this._depth = depth; }
internal ColumnBinding(OleDbDataReader dataReader, int index, int indexForAccessor, int indexWithinAccessor, OleDbParameter parameter, RowBinding rowbinding, Bindings bindings, tagDBBINDING binding, int offset, bool ifIRowsetElseIRow) { Debug.Assert(null != rowbinding, "null rowbinding"); Debug.Assert(null != bindings, "null bindings"); Debug.Assert(ODB.SizeOf_tagDBBINDING <= offset, "invalid offset" + offset); _dataReader = dataReader; _rowbinding = rowbinding; _bindings = bindings; _index = index; _indexForAccessor = indexForAccessor; _indexWithinAccessor = indexWithinAccessor; if (null != parameter) { _parameter = parameter; _parameterChangeID = parameter.ChangeID; } _offsetStatus = binding.obStatus.ToInt32() + offset; _offsetLength = binding.obLength.ToInt32() + offset; _offsetValue = binding.obValue.ToInt32() + offset; Debug.Assert(0 <= _offsetStatus, "negative _offsetStatus"); Debug.Assert(0 <= _offsetLength, "negative _offsetLength"); Debug.Assert(0 <= _offsetValue, "negative _offsetValue"); _ordinal = binding.iOrdinal.ToInt32(); _maxLen = binding.cbMaxLen.ToInt32(); _wType = binding.wType; _precision = binding.bPrecision; _ifIRowsetElseIRow = ifIRowsetElseIRow; SetSize(Bindings.ParamSize.ToInt32()); }
// may be called from either // OleDbDataReader.Close/Dispose // via OleDbCommand.Dispose or OleDbConnection.Close internal void CloseFromDataReader(Bindings bindings) { if (null != bindings) { if (canceling) { bindings.Dispose(); Debug.Assert(_dbBindings == bindings, "bindings with two owners"); } else { bindings.ApplyOutputParameters(); ParameterBindings = bindings; } } _hasDataReader = false; }
private void CreateAccessor() { Debug.Assert(System.Data.CommandType.Text == CommandType || System.Data.CommandType.StoredProcedure == CommandType, "CreateAccessor: incorrect CommandType"); Debug.Assert(null == _dbBindings, "CreateAccessor: already has dbBindings"); Debug.Assert(HasParameters(), "CreateAccessor: unexpected, no parameter collection"); // do this first in-case the command doesn't support parameters UnsafeNativeMethods.ICommandWithParameters commandWithParameters = ICommandWithParameters(); OleDbParameterCollection collection = _parameters; OleDbParameter[] parameters = new OleDbParameter[collection.Count]; collection.CopyTo(parameters, 0); // _dbBindings is used as a switch during ExecuteCommand, so don't set it until everything okay Bindings bindings = new Bindings(parameters, collection.ChangeID); for (int i = 0; i < parameters.Length; ++i) { bindings.ForceRebind |= parameters[i].BindParameter(i, bindings); } bindings.AllocateForAccessor(null, 0, 0); ApplyParameterBindings(commandWithParameters, bindings.BindInfo); UnsafeNativeMethods.IAccessor iaccessor = IAccessor(); OleDbHResult hr = bindings.CreateAccessor(iaccessor, ODB.DBACCESSOR_PARAMETERDATA); if (hr < 0) { ProcessResults(hr); } _dbBindings = bindings; }
internal Bindings TakeBindingOwnerShip() { Bindings bindings = _dbBindings; _dbBindings = null; return bindings; }
// ctor for an ICommandText, IMultipleResults, IRowset, IRow // ctor for an ADODB.Recordset, ADODB.Record or Hierarchial resultset internal OleDbDataReader(OleDbConnection connection, OleDbCommand command, int depth, CommandBehavior commandBehavior) { OleDbConnection.VerifyExecutePermission(); _connection = connection; _command = command; _commandBehavior = commandBehavior; if ((null != command) && (0 == _depth)) { _parameterBindings = command.TakeBindingOwnerShip(); } _depth = depth; }
override public void Close() { IntPtr hscp; Bid.ScopeEnter(out hscp, "<oledb.OleDbDataReader.Close|API> %d#\n", ObjectID); try { OleDbConnection con = _connection; OleDbCommand cmd = _command; Bindings bindings = _parameterBindings; _connection = null; _command = null; _parameterBindings = null; _isClosed = true; DisposeOpenResults(); _hasRows = false; if ((null != cmd) && cmd.canceling) { // MDAC 68964 DisposeNativeMultipleResults(); if (null != bindings) { bindings.CloseFromConnection(); bindings = null; } } else { UnsafeNativeMethods.IMultipleResults multipleResults = _imultipleResults; _imultipleResults = null; if (null != multipleResults) { // if we don't have a cmd, same as a cancel (don't call NextResults) which is ADODB behavior try { // tricky code path is an exception is thrown // causing connection to do a ResetState and connection.Close // resulting in OleDbCommand.CloseFromConnection if ((null != cmd) && !cmd.canceling) { // MDAC 71435 IntPtr affected = IntPtr.Zero; OleDbException nextResultsFailure = NextResults(multipleResults, null, cmd, out affected); _recordsAffected = AddRecordsAffected(_recordsAffected, affected); if (null != nextResultsFailure) { throw nextResultsFailure; } } } finally { if (null != multipleResults) { Marshal.ReleaseComObject(multipleResults); } } } } if ((null != cmd) && (0 == _depth)) { // return bindings back to the cmd after closure of root DataReader cmd.CloseFromDataReader(bindings); // MDAC 52283 } if (null != con) { con.RemoveWeakReference(this); // if the DataReader is Finalized it will not close the connection if (IsCommandBehavior(CommandBehavior.CloseConnection)) { con.Close(); } } // release unmanaged objects RowHandleBuffer rowHandleNativeBuffer = _rowHandleNativeBuffer; _rowHandleNativeBuffer = null; if (null != rowHandleNativeBuffer) { rowHandleNativeBuffer.Dispose(); } } finally { Bid.ScopeLeave(ref hscp); } }
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()); }
// 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 ColumnBinding[] SetBindings(OleDbDataReader dataReader, Bindings bindings, int indexStart, int indexForAccessor, OleDbParameter[] parameters, tagDBBINDING[] dbbindings, bool ifIRowsetElseIRow) { bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { base.DangerousAddRef(ref success); IntPtr handle = base.DangerousGetHandle(); for (int j = 0; j < dbbindings.Length; j++) { IntPtr ptr = ADP.IntPtrOffset(handle, j * ODB.SizeOf_tagDBBINDING); Marshal.StructureToPtr(dbbindings[j], ptr, false); } } finally { if (success) { base.DangerousRelease(); } } ColumnBinding[] bindingArray = new ColumnBinding[dbbindings.Length]; for (int i = 0; i < bindingArray.Length; i++) { int index = indexStart + i; OleDbParameter parameter = (parameters != null) ? parameters[index] : null; bindingArray[i] = new ColumnBinding(dataReader, index, indexForAccessor, i, parameter, this, bindings, dbbindings[i], this._headerLength, ifIRowsetElseIRow); } return bindingArray; }
private Bindings[] CreateBindingsFromMetaData(bool allowMultipleAccessor) { int count = 0; int num8 = 0; System.Data.OleDb.MetaData[] dataArray = this._metadata; int[] numArray = new int[dataArray.Length]; int[] numArray2 = new int[dataArray.Length]; if (allowMultipleAccessor) { if (this._irowset != null) { for (int k = 0; k < numArray.Length; k++) { numArray[k] = count; numArray2[k] = num8; num8++; } if (0 < num8) { count++; } } else if (this._irow != null) { for (int m = 0; m < numArray.Length; m++) { numArray[m] = m; numArray2[m] = 0; } count = dataArray.Length; } } else { for (int n = 0; n < numArray.Length; n++) { numArray[n] = 0; numArray2[n] = n; } count = 1; } Bindings[] bindingsArray = new Bindings[count]; count = 0; for (int i = 0; i < dataArray.Length; i++) { Bindings bindings = bindingsArray[numArray[i]]; if (bindings == null) { count = 0; for (int num12 = i; (num12 < dataArray.Length) && (count == numArray2[num12]); num12++) { count++; } bindingsArray[numArray[i]] = bindings = new Bindings(this, null != this._irowset, count); } System.Data.OleDb.MetaData data = dataArray[i]; int fixlen = data.type.fixlen; short wType = data.type.wType; if (-1 != data.size) { if (data.type.islong) { fixlen = ADP.PtrSize; wType = (short) (((ushort) wType) | 0x4000); } else if (-1 == fixlen) { if (0x2000 < data.size) { fixlen = ADP.PtrSize; wType = (short) (((ushort) wType) | 0x4000); } else if ((130 == wType) && (-1 != data.size)) { fixlen = (data.size * 2) + 2; } else { fixlen = data.size; } } } else if (fixlen < 0) { fixlen = ADP.PtrSize; wType = (short) (((ushort) wType) | 0x4000); } num8 = numArray2[i]; bindings.CurrentIndex = num8; bindings.Ordinal = data.ordinal; bindings.Part = data.type.dbPart; bindings.Precision = data.precision; bindings.Scale = data.scale; bindings.DbType = wType; bindings.MaxLen = fixlen; if (Bid.AdvancedOn) { Bid.Trace("<oledb.struct.tagDBBINDING|INFO|ADV> index=%d, columnName='%ls'\n", i, data.columnName); } } int index = 0; int indexStart = 0; for (int j = 0; j < bindingsArray.Length; j++) { indexStart = bindingsArray[j].AllocateForAccessor(this, indexStart, j); ColumnBinding[] bindingArray = bindingsArray[j].ColumnBindings(); for (int num10 = 0; num10 < bindingArray.Length; num10++) { dataArray[index].columnBinding = bindingArray[num10]; dataArray[index].bindings = bindingsArray[j]; index++; } } this._bindings = bindingsArray; return bindingsArray; }
public override void Close() { IntPtr ptr2; Bid.ScopeEnter(out ptr2, "<oledb.OleDbDataReader.Close|API> %d#\n", this.ObjectID); try { OleDbConnection connection = this._connection; OleDbCommand command = this._command; Bindings bindings = this._parameterBindings; this._connection = null; this._command = null; this._parameterBindings = null; this._isClosed = true; this.DisposeOpenResults(); this._hasRows = false; if ((command != null) && command.canceling) { this.DisposeNativeMultipleResults(); if (bindings != null) { bindings.CloseFromConnection(); bindings = null; } } else { UnsafeNativeMethods.IMultipleResults imultipleResults = this._imultipleResults; this._imultipleResults = null; if (imultipleResults != null) { try { if ((command != null) && !command.canceling) { IntPtr zero = IntPtr.Zero; OleDbException exception = NextResults(imultipleResults, null, command, out zero); this._recordsAffected = AddRecordsAffected(this._recordsAffected, zero); if (exception != null) { throw exception; } } } finally { if (imultipleResults != null) { Marshal.ReleaseComObject(imultipleResults); } } } } if ((command != null) && (this._depth == 0)) { command.CloseFromDataReader(bindings); } if (connection != null) { connection.RemoveWeakReference(this); if (this.IsCommandBehavior(CommandBehavior.CloseConnection)) { connection.Close(); } } RowHandleBuffer buffer = this._rowHandleNativeBuffer; this._rowHandleNativeBuffer = null; if (buffer != null) { buffer.Dispose(); } } finally { Bid.ScopeLeave(ref ptr2); } }
private void CreateAccessor() { System.Data.Common.UnsafeNativeMethods.ICommandWithParameters commandWithParameters = this.ICommandWithParameters(); OleDbParameterCollection parameters = this._parameters; OleDbParameter[] array = new OleDbParameter[parameters.Count]; parameters.CopyTo(array, 0); Bindings bindings = new Bindings(array, parameters.ChangeID); for (int i = 0; i < array.Length; i++) { bindings.ForceRebind |= array[i].BindParameter(i, bindings); } bindings.AllocateForAccessor(null, 0, 0); this.ApplyParameterBindings(commandWithParameters, bindings.BindInfo); System.Data.Common.UnsafeNativeMethods.IAccessor iaccessor = this.IAccessor(); OleDbHResult hr = bindings.CreateAccessor(iaccessor, 4); if (hr < OleDbHResult.S_OK) { this.ProcessResults(hr); } this._dbBindings = bindings; }
private void CloseInternalParameters() { Bindings bindings = this._dbBindings; this._dbBindings = null; if (bindings != null) { bindings.Dispose(); } }
internal void CloseFromDataReader(Bindings bindings) { if (bindings != null) { if (this.canceling) { bindings.Dispose(); } else { bindings.ApplyOutputParameters(); this.ParameterBindings = bindings; } } this._hasDataReader = false; }
private void CloseInternalParameters() { Debug.Assert(null != _connection, "no connection, CloseInternalParameters"); Bindings bindings = _dbBindings; _dbBindings = null; if (null != bindings) { bindings.Dispose(); } }
internal ColumnBinding[] SetBindings(OleDbDataReader dataReader, Bindings bindings, int indexStart, int indexForAccessor, OleDbParameter[] parameters, tagDBBINDING[] dbbindings, bool ifIRowsetElseIRow) { Debug.Assert(null != bindings, "null bindings"); Debug.Assert(dbbindings.Length == BindingCount(), "count mismatch"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr buffer = DangerousGetHandle(); for(int i = 0; i < dbbindings.Length; ++i) { IntPtr ptr = ADP.IntPtrOffset(buffer, (i * ODB.SizeOf_tagDBBINDING)); Marshal.StructureToPtr(dbbindings[i], ptr, false/*deleteold*/); } } finally { if (mustRelease) { DangerousRelease(); } } ColumnBinding[] columns = new ColumnBinding[dbbindings.Length]; for(int indexWithinAccessor = 0; indexWithinAccessor < columns.Length; ++indexWithinAccessor) { int index = indexStart + indexWithinAccessor; OleDbParameter parameter = ((null != parameters) ? parameters[index] : null); columns[indexWithinAccessor] = new ColumnBinding( dataReader, index, indexForAccessor, indexWithinAccessor, parameter, this, bindings, dbbindings[indexWithinAccessor], _headerLength, ifIRowsetElseIRow); } return columns; }
private Bindings[] CreateBindingsFromMetaData(bool allowMultipleAccessor) { int bindingCount = 0; int currentBindingIndex = 0; MetaData[] metadata = _metadata; int[] indexToBinding = new int[metadata.Length]; int[] indexWithinBinding = new int[metadata.Length]; // walk through the schemaRows to determine the number of binding groups if (allowMultipleAccessor) { if (null != _irowset) { for (int i = 0; i < indexToBinding.Length; ++i) { indexToBinding[i] = bindingCount; indexWithinBinding[i] = currentBindingIndex; #if false // @denote: single/multiple Accessors if ((bindingCount < 2) && IsLong(metadata[i].flags)) { bindingCount++; currentBindingIndex = 0; } else { currentBindingIndex++; } #elif false // @devnote: one accessor per column option bindingCount++; currentBindingIndex = 0; #else // @devnote: one accessor only for IRowset currentBindingIndex++; #endif } if (0 < currentBindingIndex) { // when blob is not the last column bindingCount++; } } else if (null != _irow) { for (int i = 0; i < indexToBinding.Length; ++i) { indexToBinding[i] = i; indexWithinBinding[i] = 0; } bindingCount = metadata.Length; } } else { for (int i = 0; i < indexToBinding.Length; ++i) { indexToBinding[i] = 0; indexWithinBinding[i] = i; } bindingCount = 1; } Bindings bindings; Bindings[] dbbindings = new Bindings[bindingCount]; bindingCount = 0; // for every column, build tagDBBinding info for (int index = 0; index < metadata.Length; ++index) { Debug.Assert(indexToBinding[index] < dbbindings.Length, "bad indexToAccessor"); bindings = dbbindings[indexToBinding[index]]; if (null == bindings) { bindingCount = 0; for (int i = index; (i < metadata.Length) && (bindingCount == indexWithinBinding[i]); ++i) { bindingCount++; } dbbindings[indexToBinding[index]] = bindings = new Bindings((OleDbDataReader)this, (null != _irowset), bindingCount); // runningTotal is buffered to start values on 16-byte boundary // the first columnCount * 8 bytes are for the length and status fields //bindings.DataBufferSize = (bindingCount + (bindingCount % 2)) * sizeof_int64; } MetaData info = metadata[index]; int maxLen = info.type.fixlen; short getType = info.type.wType; Debug.Assert(NativeDBType.STR != getType, "Should have bound as WSTR"); Debug.Assert(!NativeDBType.HasHighBit(getType), "CreateAccessor - unexpected high bits on datatype"); if (-1 != info.size) { if (info.type.islong) { maxLen = ADP.PtrSize; getType = (short)((ushort) getType | (ushort) NativeDBType.BYREF); } else if (-1 == maxLen) { // @devnote: not using provider owned memory for PDC, no one really supports it anyway. /*if (((null != connection) && connection.PropertyGetProviderOwnedMemory()) || ((null != command) && command.Connection.PropertyGetProviderOwnedMemory())) { bindings.MemOwner = DBMemOwner.ProviderOwned; bindings.MaxLen = ADP.PtrSize; bindings.DbType = (short) (getType | DbType.BYREF); } else*/ if (ODB.LargeDataSize < info.size) { maxLen = ADP.PtrSize; getType = (short)((ushort) getType | (ushort)NativeDBType.BYREF); } else if ((NativeDBType.WSTR == getType) && (-1 != info.size)) { // WebData 99298 maxLen = info.size * 2 + 2; } else { maxLen = info.size; } } } else if (maxLen < 0) { // if variable length and no defined size we require this to be byref at this time /*if (((null != connection) && connection.PropertyGetProviderOwnedMemory()) || ((null != command) && command.Connection.PropertyGetProviderOwnedMemory())) { bindings.MemOwner = DBMemOwner.ProviderOwned; }*/ maxLen = ADP.PtrSize; getType = (short)((ushort) getType | (ushort)NativeDBType.BYREF); } currentBindingIndex = indexWithinBinding[index]; bindings.CurrentIndex = currentBindingIndex; bindings.Ordinal = info.ordinal; bindings.Part = info.type.dbPart; bindings.Precision = (byte) info.precision; bindings.Scale = (byte) info.scale; bindings.DbType = (short) getType; bindings.MaxLen = maxLen; // also increments databuffer size (uses DbType) //bindings.ValueOffset = // set via MaxLen //bindings.LengthOffset = // set via MaxLen //bindings.StatusOffset = // set via MaxLen //bindings.TypeInfoPtr = 0; //bindings.ObjectPtr = 0; //bindings.BindExtPtr = 0; //bindings.MemOwner = /*DBMEMOWNER_CLIENTOWNED*/0; //bindings.ParamIO = ODB.DBPARAMIO_NOTPARAM; //bindings.Flags = 0; if (Bid.AdvancedOn) { Bid.Trace("<oledb.struct.tagDBBINDING|INFO|ADV> index=%d, columnName='%ls'\n", index, info.columnName);//, bindings.bindings[index]); } } int count = 0, indexStart = 0; for (int i = 0; i < dbbindings.Length; ++i) { indexStart = dbbindings[i].AllocateForAccessor(this, indexStart, i); ColumnBinding[] columnBindings = dbbindings[i].ColumnBindings(); for (int k = 0; k < columnBindings.Length; ++k) { Debug.Assert(count == columnBindings[k].Index, "column binding mismatch"); metadata[count].columnBinding = columnBindings[k]; metadata[count].bindings = dbbindings[i]; count++; } } _bindings = dbbindings; return dbbindings; }
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(); }
// 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 = int.MaxValue; } else if (NativeDBType.WSTR == dbtype.dbType) { size = int.MaxValue / 2; } else { size = int.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) { // 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"); return(IsParameterComputed()); }