private void WriteMetaData(BulkCopySimpleResultSet internalResults) { this._stateObj.SetTimeoutSeconds(this.BulkCopyTimeout); _SqlMetaDataSet metaData = internalResults[1].MetaData; this._stateObj._outputMessageType = 7; this._parser.WriteBulkCopyMetaData(metaData, this._sortedColumnMappings.Count, this._stateObj); }
internal void SetMetaData(_SqlMetaDataSet metadata) { this.resultSet = new Result(metadata); this._results.Add(this.resultSet); this.indexmap = new int[this.resultSet.MetaData.Length]; for (int i = 0; i < this.indexmap.Length; i++) { this.indexmap[i] = i; } }
internal void SetAltMetaData(_SqlMetaDataSet altMetaDataSet) { int id = altMetaDataSet.id; for (int i = 0; i < this.altMetaDataSetArray.Count; i++) { if (this.altMetaDataSetArray[i].id == id) { this.altMetaDataSetArray[i] = altMetaDataSet; return; } } this.altMetaDataSetArray.Add(altMetaDataSet); }
internal void SetAltMetaData(_SqlMetaDataSet altMetaDataSet) { // If altmetadata with same id is found, override it rather than adding a new one int newId = altMetaDataSet.id; for (int i = 0; i < _altMetaDataSetArray.Count; i++) { if (_altMetaDataSetArray[i].id == newId) { // override the existing metadata with the same id _altMetaDataSetArray[i] = altMetaDataSet; return; } } // if we did not find metadata to override, add as new _altMetaDataSetArray.Add(altMetaDataSet); }
private _SqlMetaDataSet(_SqlMetaDataSet original) { this.id = original.id; // although indexMap is not immutable, in practice it is initialized once and then passed around this.indexMap = original.indexMap; this.visibleColumns = original.visibleColumns; if (original._metaDataArray == null) { _metaDataArray = null; } else { _metaDataArray = new _SqlMetaData[original._metaDataArray.Length]; for (int idx = 0; idx < _metaDataArray.Length; idx++) { _metaDataArray[idx] = (_SqlMetaData)original._metaDataArray[idx].Clone(); } } }
internal void WriteBulkCopyMetaData(_SqlMetaDataSet metadataCollection, int count, TdsParserStateObject stateObj) { if (!(State == TdsParserState.OpenNotLoggedIn || State == TdsParserState.OpenLoggedIn)) { throw ADP.ClosedConnectionError(); } stateObj.WriteByte(TdsEnums.SQLCOLMETADATA); WriteShort(count, stateObj); // Write CEK table - 0 count WriteCekTable(metadataCollection, stateObj); for (int i = 0; i < metadataCollection.Length; i++) { if (metadataCollection[i] != null) { _SqlMetaData md = metadataCollection[i]; // read user type - 4 bytes Yukon, 2 backwards if (IsYukonOrNewer) { WriteInt(0x0, stateObj); } else { WriteShort(0x0000, stateObj); } // Write the flags UInt16 flags; flags = (UInt16)(md.updatability << 2); flags |= (UInt16)(md.isNullable ? (UInt16)TdsEnums.Nullable : (UInt16)0); flags |= (UInt16)(md.isIdentity ? (UInt16)TdsEnums.Identity : (UInt16)0); // Write the next byte of flags if (_serverSupportsColumnEncryption) { // TCE Supported if (ShouldEncryptValuesForBulkCopy()) { // TCE enabled on connection options flags |= (UInt16)(md.isEncrypted ? (UInt16)(TdsEnums.IsEncrypted << 8) : (UInt16)0); } } WriteShort(flags, stateObj);// write the flags // todo: // for xml WriteTokenLength results in a no-op // discuss this with blaine ... // ([....]) xml datatype does not have token length in its metadata. So it should be a noop. switch (md.type) { case SqlDbType.Decimal: stateObj.WriteByte(md.tdsType); WriteTokenLength(md.tdsType, md.length, stateObj); stateObj.WriteByte(md.precision); stateObj.WriteByte(md.scale); break; case SqlDbType.Xml: // stateObj.WriteByteArray(s_xmlMetadataSubstituteSequence, s_xmlMetadataSubstituteSequence.Length, 0); break; case SqlDbType.Udt: stateObj.WriteByte(TdsEnums.SQLBIGVARBINARY); WriteTokenLength(TdsEnums.SQLBIGVARBINARY, md.length, stateObj); break; case SqlDbType.Date: stateObj.WriteByte(md.tdsType); break; case SqlDbType.Time: case SqlDbType.DateTime2: case SqlDbType.DateTimeOffset: stateObj.WriteByte(md.tdsType); stateObj.WriteByte(md.scale); break; default: stateObj.WriteByte(md.tdsType); WriteTokenLength(md.tdsType, md.length, stateObj); if (md.metaType.IsCharType && _isShiloh) { WriteUnsignedInt(md.collation.info, stateObj); stateObj.WriteByte(md.collation.sortId); } break; } if (md.metaType.IsLong && !md.metaType.IsPlp) { WriteShort(md.tableName.Length, stateObj); WriteString(md.tableName, stateObj); } WriteCryptoMetadata(md, stateObj); stateObj.WriteByte((byte)md.column.Length); WriteString(md.column, stateObj); } } // end for loop }
protected override void Dispose(bool disposing) { if (disposing) { this._cachedMetaData = null; } base.Dispose(disposing); }
internal bool TrySkipRow(_SqlMetaDataSet columns, int startCol, TdsParserStateObject stateObj) { for (int i = startCol; i < columns.Length; i++) { _SqlMetaData md = columns[i]; if (!TrySkipValue(md, i, stateObj)) { return false; } } return true; }
internal void SkipRow(_SqlMetaDataSet columns, TdsParserStateObject stateObj) { this.SkipRow(columns, 0, stateObj); }
internal void Snap() { _snapshotInBuffs.Clear(); _snapshotInBuffCurrent = 0; _snapshotInBytesUsed = _stateObj._inBytesUsed; _snapshotInBytesPacket = _stateObj._inBytesPacket; _snapshotPendingData = _stateObj._pendingData; _snapshotErrorTokenReceived = _stateObj._errorTokenReceived; _snapshotMessageStatus = _stateObj._messageStatus; // _nullBitmapInfo must be cloned before it is updated _snapshotNullBitmapInfo = _stateObj._nullBitmapInfo; _snapshotLongLen = _stateObj._longlen; _snapshotLongLenLeft = _stateObj._longlenleft; _snapshotCleanupMetaData = _stateObj._cleanupMetaData; // _cleanupAltMetaDataSetArray must be cloned bofore it is updated _snapshotCleanupAltMetaDataSetArray = _stateObj._cleanupAltMetaDataSetArray; _snapshotHasOpenResult = _stateObj._hasOpenResult; _snapshotReceivedColumnMetadata = _stateObj._receivedColMetaData; _snapshotAttentionReceived = _stateObj._attentionReceived; #if DEBUG _rollingPend = 0; _rollingPendCount = 0; _stateObj._lastStack = null; Debug.Assert(_stateObj._bTmpRead == 0, "Has partially read data when snapshot taken"); Debug.Assert(_stateObj._partialHeaderBytesRead == 0, "Has partially read header when shapshot taken"); #endif PushBuffer(_stateObj._inBuff, _stateObj._inBytesRead); }
// callback function for the tdsparser // note that setting the metadata adds a resultset // internal void SetMetaData(_SqlMetaDataSet metadata) { resultSet = new Result(metadata); _results.Add(resultSet); indexmap = new int[resultSet.MetaData.Length]; for(int i = 0; i < indexmap.Length; i++) { indexmap[i] = i; } }
internal void WriteBulkCopyMetaData(_SqlMetaDataSet metadataCollection, int count, TdsParserStateObject stateObj) { this.WriteByte(0x81, stateObj); this.WriteShort(count, stateObj); for (int i = 0; i < metadataCollection.Length; i++) { if (metadataCollection[i] == null) { continue; } _SqlMetaData data = metadataCollection[i]; if (this.IsYukonOrNewer) { this.WriteInt(0, stateObj); } else { this.WriteShort(0, stateObj); } ushort v = (ushort) (data.updatability << 2); v = (ushort) (v | (data.isNullable ? 1 : 0)); v = (ushort) (v | (data.isIdentity ? 0x10 : 0)); this.WriteShort(v, stateObj); switch (data.type) { case SqlDbType.Xml: this.WriteByteArray(s_xmlMetadataSubstituteSequence, s_xmlMetadataSubstituteSequence.Length, 0, stateObj); break; case SqlDbType.Udt: this.WriteByte(0xa5, stateObj); this.WriteTokenLength(0xa5, data.length, stateObj); break; case SqlDbType.Date: this.WriteByte(data.tdsType, stateObj); break; case SqlDbType.Time: case SqlDbType.DateTime2: case SqlDbType.DateTimeOffset: this.WriteByte(data.tdsType, stateObj); this.WriteByte(data.scale, stateObj); break; case SqlDbType.Decimal: this.WriteByte(data.tdsType, stateObj); this.WriteTokenLength(data.tdsType, data.length, stateObj); this.WriteByte(data.precision, stateObj); this.WriteByte(data.scale, stateObj); break; default: this.WriteByte(data.tdsType, stateObj); this.WriteTokenLength(data.tdsType, data.length, stateObj); if (data.metaType.IsCharType && this._isShiloh) { this.WriteUnsignedInt(data.collation.info, stateObj); this.WriteByte(data.collation.sortId, stateObj); } break; } if (data.metaType.IsLong && !data.metaType.IsPlp) { this.WriteShort(data.tableName.Length, stateObj); this.WriteString(data.tableName, stateObj); } this.WriteByte((byte) data.column.Length, stateObj); this.WriteString(data.column, stateObj); } }
public override void Prepare() { SqlConnection.ExecutePermission.Demand(); this._pendingCancel = false; if ((this._activeConnection == null) || !this._activeConnection.IsContextConnection) { IntPtr ptr; SqlStatistics statistics = null; SqlDataReader reader = null; Bid.ScopeEnter(out ptr, "<sc.SqlCommand.Prepare|API> %d#", this.ObjectID); statistics = SqlStatistics.StartTimer(this.Statistics); if ((this.IsPrepared && !this.IsDirty) || ((this.CommandType == System.Data.CommandType.StoredProcedure) || ((System.Data.CommandType.Text == this.CommandType) && (this.GetParameterCount(this._parameters) == 0)))) { if (this.Statistics != null) { this.Statistics.SafeIncrement(ref this.Statistics._prepares); } this._hiddenPrepare = false; } else { bool flag = true; SNIHandle target = null; RuntimeHelpers.PrepareConstrainedRegions(); try { target = SqlInternalConnection.GetBestEffortCleanupTarget(this._activeConnection); this.ValidateCommand("Prepare", false); this.GetStateObject(); if (this._parameters != null) { int count = this._parameters.Count; for (int i = 0; i < count; i++) { this._parameters[i].Prepare(this); } } reader = this.InternalPrepare(CommandBehavior.Default); } catch (OutOfMemoryException exception4) { flag = false; this._activeConnection.Abort(exception4); throw; } catch (StackOverflowException exception3) { flag = false; this._activeConnection.Abort(exception3); throw; } catch (ThreadAbortException exception2) { flag = false; this._activeConnection.Abort(exception2); SqlInternalConnection.BestEffortCleanup(target); throw; } catch (Exception exception) { flag = ADP.IsCatchableExceptionType(exception); throw; } finally { if (flag) { this._hiddenPrepare = false; if (reader != null) { this._cachedMetaData = reader.MetaData; reader.Close(); } this.PutStateObject(); } } } SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref ptr); } }
internal void SetMetaData(_SqlMetaDataSet metaData, bool moreInfo) { this._metaData = metaData; this._tableNames = null; if (this._metaData != null) { this._metaData.schemaTable = null; this._data = SqlBuffer.CreateBufferArray(metaData.Length); } this._fieldNameLookup = null; if (metaData != null) { if (!moreInfo) { this._metaDataConsumed = true; if (this._parser != null) { byte num = this._stateObj.PeekByte(); if (num == 0xa9) { this._parser.Run(RunBehavior.ReturnImmediately, null, null, null, this._stateObj); num = this._stateObj.PeekByte(); } this._hasRows = 0xd1 == num; if (0x88 == num) { this._metaDataConsumed = false; } } } } else { this._metaDataConsumed = false; } this._browseModeInfoConsumed = false; }
private void ClearMetaData() { this._metaData = null; this._tableNames = null; this._fieldNameLookup = null; this._metaDataConsumed = false; this._browseModeInfoConsumed = false; }
internal void SetAltMetaDataSet(_SqlMetaDataSet metaDataSet, bool metaDataConsumed) { if (this._altMetaDataSetCollection == null) { this._altMetaDataSetCollection = new _SqlMetaDataSetCollection(); } this._altMetaDataSetCollection.SetAltMetaData(metaDataSet); this._metaDataConsumed = metaDataConsumed; if (this._metaDataConsumed && (this._parser != null)) { byte num = this._stateObj.PeekByte(); if (0xa9 == num) { this._parser.Run(RunBehavior.ReturnImmediately, this._command, this, null, this._stateObj); num = this._stateObj.PeekByte(); } this._hasRows = 0xd1 == num; } if ((metaDataSet != null) && ((this._data == null) || (this._data.Length < metaDataSet.Length))) { this._data = SqlBuffer.CreateBufferArray(metaDataSet.Length); } }
public override bool NextResult() { bool flag; SqlStatistics statistics = null; IntPtr ptr; Bid.ScopeEnter(out ptr, "<sc.SqlDataReader.NextResult|API> %d#", this.ObjectID); RuntimeHelpers.PrepareConstrainedRegions(); try { statistics = SqlStatistics.StartTimer(this.Statistics); this.SetTimeout(); if (this.IsClosed) { throw ADP.DataReaderClosed("NextResult"); } this._fieldNameLookup = null; bool flag2 = false; this._hasRows = false; if (this.IsCommandBehavior(CommandBehavior.SingleResult)) { this.CloseInternal(false); this.ClearMetaData(); return flag2; } if (this._parser != null) { while (this.ReadInternal(false)) { } } if (this._parser != null) { if (this.HasMoreResults()) { this._metaDataConsumed = false; this._browseModeInfoConsumed = false; switch (this._altRowStatus) { case ALTROWSTATUS.AltRow: { int altRowId = this._parser.GetAltRowId(this._stateObj); _SqlMetaDataSet altMetaData = this._altMetaDataSetCollection.GetAltMetaData(altRowId); if (altMetaData != null) { this._metaData = altMetaData; this._metaData.indexMap = altMetaData.indexMap; } break; } case ALTROWSTATUS.Done: this._metaData = this._altMetaDataSetCollection.metaDataSet; this._altRowStatus = ALTROWSTATUS.Null; break; default: this.ConsumeMetaData(); if (this._metaData == null) { return false; } break; } return true; } this.CloseInternal(false); this.SetMetaData(null, false); return flag2; } this.ClearMetaData(); return flag2; } catch (OutOfMemoryException exception3) { this._isClosed = true; if (this._connection != null) { this._connection.Abort(exception3); } throw; } catch (StackOverflowException exception2) { this._isClosed = true; if (this._connection != null) { this._connection.Abort(exception2); } throw; } catch (ThreadAbortException exception) { this._isClosed = true; if (this._connection != null) { this._connection.Abort(exception); } throw; } finally { SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref ptr); } return flag; }
private bool HasMoreResults() { if (this._parser != null) { if (!this.HasMoreRows()) { while (this._stateObj._pendingData) { switch (this._stateObj.PeekByte()) { case 0xd1: return true; case 0xd3: if (this._altRowStatus == ALTROWSTATUS.Null) { this._altMetaDataSetCollection.metaDataSet = this._metaData; this._metaData = null; } this._altRowStatus = ALTROWSTATUS.AltRow; this._hasRows = true; return true; case 0xfd: this._altRowStatus = ALTROWSTATUS.Null; this._metaData = null; this._altMetaDataSetCollection = null; return true; case 0x81: return true; } this._parser.Run(RunBehavior.ReturnImmediately, this._command, this, null, this._stateObj); } } else { return true; } } return false; }
private void FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, string resetOptionsString) { this.NotifyDependency(); if (runBehavior == RunBehavior.UntilDone) { try { this._stateObj.Parser.Run(RunBehavior.UntilDone, this, ds, null, this._stateObj); } catch (Exception exception2) { if (ADP.IsCatchableExceptionType(exception2)) { if (this._inPrepare) { this._inPrepare = false; this.IsDirty = true; this._execType = EXECTYPE.PREPAREPENDING; } if (ds != null) { ds.Close(); } } throw; } } if (ds != null) { ds.Bind(this._stateObj); this._stateObj = null; ds.ResetOptionsString = resetOptionsString; this._activeConnection.AddWeakReference(ds, 1); try { this._cachedMetaData = ds.MetaData; ds.IsInitialized = true; } catch (Exception exception) { if (ADP.IsCatchableExceptionType(exception)) { if (this._inPrepare) { this._inPrepare = false; this.IsDirty = true; this._execType = EXECTYPE.PREPAREPENDING; } ds.Close(); } throw; } } }
internal void SkipRow(_SqlMetaDataSet columns, int startCol, TdsParserStateObject stateObj) { for (int i = startCol; i < columns.Length; i++) { _SqlMetaData md = columns[i]; if (md.metaType.IsLong && !md.metaType.IsPlp) { byte num2 = stateObj.ReadByte(); if (num2 == 0) { continue; } this.SkipBytes(num2 + 8, stateObj); } this.SkipValue(md, stateObj); } }
private void InternalUnprepare(bool isClosing) { if (this.IsShiloh) { this._execType = EXECTYPE.PREPAREPENDING; if (isClosing) { this._prepareHandle = -1; } } else { if (this._prepareHandle != -1) { this.BuildUnprepare(); this._stateObj.Parser.TdsExecuteRPC(this._rpcArrayOf1, this.CommandTimeout, false, null, this._stateObj, System.Data.CommandType.StoredProcedure == this.CommandType); this._stateObj.Parser.Run(RunBehavior.UntilDone, this, null, null, this._stateObj); this._prepareHandle = -1; } this._execType = EXECTYPE.UNPREPARED; } this._cachedMetaData = null; if (!isClosing) { this._activeConnection.RemovePreparedCommand(this); } Bid.Trace("<sc.SqlCommand.Prepare|INFO> %d#, Command unprepared.\n", this.ObjectID); }
internal bool TryProcessMetaData(int cColumns, TdsParserStateObject stateObj, out _SqlMetaDataSet metaData) { Debug.Assert(cColumns > 0, "should have at least 1 column in metadata!"); _SqlMetaDataSet newMetaData = new _SqlMetaDataSet(cColumns); for (int i = 0; i < cColumns; i++) { if (!TryCommonProcessMetaData(stateObj, newMetaData[i])) { metaData = null; return false; } } metaData = newMetaData; return true; }
internal Result(_SqlMetaDataSet metadata) { this._metadata = metadata; this._rowset = new ArrayList(); }
// Used internally by BulkCopy only private bool TryProcessRow(_SqlMetaDataSet columns, object[] buffer, int[] map, TdsParserStateObject stateObj) { SqlBuffer data = new SqlBuffer(); for (int i = 0; i < columns.Length; i++) { _SqlMetaData md = columns[i]; Debug.Assert(md != null, "_SqlMetaData should not be null for column " + i.ToString(CultureInfo.InvariantCulture)); bool isNull; ulong len; if (!TryProcessColumnHeader(md, stateObj, i, out isNull, out len)) { return false; } if (isNull) { GetNullSqlValue(data, md); buffer[map[i]] = data.SqlValue; } else { // We only read up to 2Gb. Throw if data is larger. Very large data // should be read in chunks in sequential read mode // For Plp columns, we may have gotten only the length of the first chunk if (!TryReadSqlValue(data, md, md.metaType.IsPlp ? (Int32.MaxValue) : (int)len, stateObj)) { return false; } buffer[map[i]] = data.SqlValue; if (stateObj._longlen != 0) { throw new SqlTruncateException(Res.GetString(Res.SqlMisc_TruncationMaxDataMessage)); } } data.Clear(); } return true; }
internal bool TryProcessAltMetaData(int cColumns, TdsParserStateObject stateObj, out _SqlMetaDataSet metaData) { Debug.Assert(cColumns > 0, "should have at least 1 column in altMetaData!"); metaData = null; _SqlMetaDataSet altMetaDataSet = new _SqlMetaDataSet(cColumns, null); int[] indexMap = new int[cColumns]; if (!stateObj.TryReadUInt16(out altMetaDataSet.id)) { return false; } byte byCols; if (!stateObj.TryReadByte(out byCols)) { return false; } while (byCols > 0) { if (!stateObj.TrySkipBytes(2)) { // ignore ColNum ... return false; } byCols--; } // pass 1, read the meta data off the wire for (int i = 0; i < cColumns; i++) { // internal meta data class _SqlMetaData col = altMetaDataSet[i]; if (!stateObj.TryReadByte(out col.op)) { return false; } if (!stateObj.TryReadUInt16(out col.operand)) { return false; } // TCE is not applicable to AltMetadata. if (!TryCommonProcessMetaData(stateObj, col, null, fColMD: false, columnEncryptionSetting: SqlCommandColumnEncryptionSetting.Disabled)) { return false; } if (ADP.IsEmpty(col.column)) { // create column name from op switch (col.op) { case TdsEnums.AOPAVG: col.column = "avg"; break; case TdsEnums.AOPCNT: col.column = "cnt"; break; case TdsEnums.AOPCNTB: col.column = "cntb"; break; case TdsEnums.AOPMAX: col.column = "max"; break; case TdsEnums.AOPMIN: col.column = "min"; break; case TdsEnums.AOPSUM: col.column = "sum"; break; case TdsEnums.AOPANY: col.column = "any"; break; case TdsEnums.AOPNOOP: col.column = "noop"; break; case TdsEnums.AOPSTDEV: col.column = "stdev"; break; case TdsEnums.AOPSTDEVP: col.column = "stdevp"; break; case TdsEnums.AOPVAR: col.column = "var"; break; case TdsEnums.AOPVARP: col.column = "varp"; break; } } indexMap[i] = i; } altMetaDataSet.indexMap = indexMap; altMetaDataSet.visibleColumns = cColumns; metaData = altMetaDataSet; return true; }
internal bool TryProcessAltMetaData(int cColumns, TdsParserStateObject stateObj, out _SqlMetaDataSet metaData) { Debug.Assert(cColumns > 0, "should have at least 1 column in altMetaData!"); metaData = null; _SqlMetaDataSet altMetaDataSet = new _SqlMetaDataSet(cColumns); int[] indexMap = new int[cColumns]; if (!stateObj.TryReadUInt16(out altMetaDataSet.id)) { return false; } byte byCols; if (!stateObj.TryReadByte(out byCols)) { return false; } while (byCols > 0) { if (!stateObj.TrySkipBytes(2)) { // ignore ColNum ... return false; } byCols--; } // pass 1, read the meta data off the wire for (int i = 0; i < cColumns; i++) { // internal meta data class _SqlMetaData col = altMetaDataSet[i]; byte op; if (!stateObj.TryReadByte(out op)) { return false; } ushort operand; if (!stateObj.TryReadUInt16(out operand)) { return false; } if (!TryCommonProcessMetaData(stateObj, col)) { return false; } indexMap[i] = i; } altMetaDataSet.indexMap = indexMap; altMetaDataSet.visibleColumns = cColumns; metaData = altMetaDataSet; return true; }
internal bool TryProcessMetaData(int cColumns, TdsParserStateObject stateObj, out _SqlMetaDataSet metaData, SqlCommandColumnEncryptionSetting columnEncryptionSetting) { Debug.Assert(cColumns > 0, "should have at least 1 column in metadata!"); // Read the cipher info table first SqlTceCipherInfoTable? cipherTable = null; if (_serverSupportsColumnEncryption) { if (!TryProcessCipherInfoTable (stateObj, out cipherTable)) { metaData = null; return false; } } // Read the ColumnData fields _SqlMetaDataSet newMetaData = new _SqlMetaDataSet(cColumns, cipherTable); for (int i = 0; i < cColumns; i++) { if (!TryCommonProcessMetaData(stateObj, newMetaData[i], cipherTable, fColMD: true, columnEncryptionSetting: columnEncryptionSetting)) { metaData = null; return false; } } // DEVNOTE: cipherTable is discarded at this point since its no longer needed. metaData = newMetaData; return true; }
// augments current metadata with table and key information private bool TryProcessColInfo(_SqlMetaDataSet columns, SqlDataReader reader, TdsParserStateObject stateObj, out _SqlMetaDataSet metaData) { Debug.Assert(columns != null && columns.Length > 0, "no metadata available!"); metaData = null; for (int i = 0; i < columns.Length; i++) { _SqlMetaData col = columns[i]; byte ignored; if (!stateObj.TryReadByte(out ignored)) { // colnum, ignore return false; } if (!stateObj.TryReadByte(out ignored)) { // tablenum, ignore return false; } // interpret status byte status; if (!stateObj.TryReadByte(out status)) { return false; } col.isKey = (TdsEnums.SQLKey == (status & TdsEnums.SQLKey)); col.isHidden = (TdsEnums.SQLHidden == (status & TdsEnums.SQLHidden)); // read off the base table name if it is different than the select list column name if (TdsEnums.SQLDifferentName == (status & TdsEnums.SQLDifferentName)) { byte len; if (!stateObj.TryReadByte(out len)) { return false; } if (!stateObj.TrySkipBytes(len * ADP.CharSize)) { return false; } } if (TdsEnums.SQLExpression == (status & TdsEnums.SQLExpression)) { col.updatability = 0; } } // set the metadata so that the stream knows some metadata info has changed metaData = columns; return true; }
// augments current metadata with table and key information private bool TryProcessColInfo(_SqlMetaDataSet columns, SqlDataReader reader, TdsParserStateObject stateObj, out _SqlMetaDataSet metaData) { Debug.Assert(columns != null && columns.Length > 0, "no metadata available!"); metaData = null; for (int i = 0; i < columns.Length; i++) { _SqlMetaData col = columns[i]; byte ignored; if (!stateObj.TryReadByte(out ignored)) { // colnum, ignore return false; } if (!stateObj.TryReadByte(out col.tableNum)) { return false; } // interpret status byte status; if (!stateObj.TryReadByte(out status)) { return false; } col.isDifferentName = (TdsEnums.SQLDifferentName == (status & TdsEnums.SQLDifferentName)); col.isExpression = (TdsEnums.SQLExpression == (status & TdsEnums.SQLExpression)); col.isKey = (TdsEnums.SQLKey == (status & TdsEnums.SQLKey)); col.isHidden = (TdsEnums.SQLHidden == (status & TdsEnums.SQLHidden)); // read off the base table name if it is different than the select list column name if (col.isDifferentName) { byte len; if (!stateObj.TryReadByte(out len)) { return false; } if (!stateObj.TryReadString(len, out col.baseColumn)) { return false; } } // Fixup column name - only if result of a table - that is if it was not the result of // an expression. if ((reader.TableNames != null) && (col.tableNum > 0)) { Debug.Assert(reader.TableNames.Length >= col.tableNum, "invalid tableNames array!"); col.multiPartTableName = reader.TableNames[col.tableNum - 1]; } // MDAC 60109: expressions are readonly if (col.isExpression) { col.updatability = 0; } } // set the metadata so that the stream knows some metadata info has changed metaData = columns; return true; }
internal bool TrySkipRow(_SqlMetaDataSet columns, TdsParserStateObject stateObj) { return TrySkipRow(columns, 0, stateObj); }
/// <summary> /// Loads the column encryptions keys into cache. This will read the master key info, /// decrypt the CEK and keep it ready for encryption. /// </summary> /// <returns></returns> internal void LoadColumnEncryptionKeys (_SqlMetaDataSet metadataCollection, string serverName) { if (_serverSupportsColumnEncryption && ShouldEncryptValuesForBulkCopy()) { for (int col = 0; col < metadataCollection.Length; col++) { if (null != metadataCollection[col]) { _SqlMetaData md = metadataCollection[col]; if (md.isEncrypted) { SqlSecurityUtility.DecryptSymmetricKey(md.cipherMD, serverName); } } } } }
internal void WriteBulkCopyMetaData(_SqlMetaDataSet metadataCollection, int count, TdsParserStateObject stateObj) { if (!(State == TdsParserState.OpenNotLoggedIn || State == TdsParserState.OpenLoggedIn)) { throw ADP.ClosedConnectionError(); } stateObj.WriteByte(TdsEnums.SQLCOLMETADATA); WriteShort(count, stateObj); for (int i = 0; i < metadataCollection.Length; i++) { if (metadataCollection[i] != null) { _SqlMetaData md = metadataCollection[i]; // read user type - 4 bytes Yukon, 2 backwards WriteInt(0x0, stateObj); UInt16 flags; flags = (UInt16)(md.updatability << 2); flags |= (UInt16)(md.isNullable ? (UInt16)TdsEnums.Nullable : (UInt16)0); flags |= (UInt16)(md.isIdentity ? (UInt16)TdsEnums.Identity : (UInt16)0); WriteShort(flags, stateObj); // write the flags switch (md.type) { case SqlDbType.Decimal: stateObj.WriteByte(md.tdsType); WriteTokenLength(md.tdsType, md.length, stateObj); stateObj.WriteByte(md.precision); stateObj.WriteByte(md.scale); break; case SqlDbType.Xml: stateObj.WriteByteArray(s_xmlMetadataSubstituteSequence, s_xmlMetadataSubstituteSequence.Length, 0); break; case SqlDbType.Udt: throw ADP.DbTypeNotSupported(SqlDbType.Udt.ToString()); case SqlDbType.Date: stateObj.WriteByte(md.tdsType); break; case SqlDbType.Time: case SqlDbType.DateTime2: case SqlDbType.DateTimeOffset: stateObj.WriteByte(md.tdsType); stateObj.WriteByte(md.scale); break; default: stateObj.WriteByte(md.tdsType); WriteTokenLength(md.tdsType, md.length, stateObj); if (md.metaType.IsCharType) { WriteUnsignedInt(md.collation.info, stateObj); stateObj.WriteByte(md.collation.sortId); } break; } if (md.metaType.IsLong && !md.metaType.IsPlp) { WriteShort(md.tableName.Length, stateObj); WriteString(md.tableName, stateObj); } stateObj.WriteByte((byte)md.column.Length); WriteString(md.column, stateObj); } } // end for loop }
/// <summary> /// Writes a CEK Table (as part of COLMETADATA token) for bulk copy. /// </summary> /// <returns></returns> internal void WriteCekTable (_SqlMetaDataSet metadataCollection, TdsParserStateObject stateObj) { if (!_serverSupportsColumnEncryption) { return; } // If no cek table is present, send a count of 0 for table size // Note- Cek table (with 0 entries) will be present if TCE // was enabled and server supports it! // OR if encryption was disabled in connection options if (!metadataCollection.cekTable.HasValue || !ShouldEncryptValuesForBulkCopy()) { WriteShort(0x00, stateObj); return; } SqlTceCipherInfoTable cekTable = metadataCollection.cekTable.Value; ushort count = (ushort)cekTable.Size; WriteShort(count, stateObj); WriteEncryptionEntries(ref cekTable, stateObj); }