DBCommandBuilder.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / Common / DBCommandBuilder.cs / 1 / DBCommandBuilder.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.Common {
 
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Text; 
    using System.Text.RegularExpressions;
 
#if WINFSInternalOnly
    internal
#else
    public 
#endif
    abstract class DbCommandBuilder : Component { // V1.2.3300 
        private class ParameterNames { 
            private const string DefaultOriginalPrefix = "Original_";
            private const string DefaultIsNullPrefix = "IsNull_"; 

            // we use alternative prefix if the default prefix fails parametername validation
            private const string AlternativeOriginalPrefix = "original";
            private const string AlternativeIsNullPrefix = "isnull"; 
            private const string AlternativeOriginalPrefix2 = "ORIGINAL";
            private const string AlternativeIsNullPrefix2 = "ISNULL"; 
 
            private string _originalPrefix;
            private string _isNullPrefix; 

            private Regex _parameterNameParser;
            private DbCommandBuilder _dbCommandBuilder;
            private string[] _baseParameterNames; 
            private string[] _originalParameterNames;
            private string[] _nullParameterNames; 
            private bool[] _isMutatedName; 
            private int _count;
            private int _genericParameterCount; 
            private int _adjustedParameterNameMaxLength;

            internal ParameterNames(DbCommandBuilder dbCommandBuilder, DbSchemaRow[] schemaRows) {
                _dbCommandBuilder = dbCommandBuilder; 
                _baseParameterNames = new string[schemaRows.Length];
                _originalParameterNames = new string[schemaRows.Length]; 
                _nullParameterNames = new string[schemaRows.Length]; 
                _isMutatedName = new bool[schemaRows.Length];
                _count = schemaRows.Length; 
                _parameterNameParser = new Regex(_dbCommandBuilder.ParameterNamePattern, RegexOptions.ExplicitCapture | RegexOptions.Singleline);

                SetAndValidateNamePrefixes();
                _adjustedParameterNameMaxLength = GetAdjustedParameterNameMaxLength(); 

                // Generate the baseparameter names and remove conflicting names 
                // No names will be generated for any name that is rejected due to invalid prefix, regex violation or 
                // name conflict after mutation.
                // All null values will be replaced with generic parameter names 
                //
                for (int i = 0; i < schemaRows.Length; i++) {
                    if (null == schemaRows[i]) {
                        continue; 
                    }
                    bool isMutatedName = false; 
                    string columnName = schemaRows[i].ColumnName; 

                    // all names that start with original- or isNullPrefix are invalid 
                    if (null != _originalPrefix) {
                        if (columnName.StartsWith(_originalPrefix, StringComparison.OrdinalIgnoreCase)) {
                            continue;
                        } 
                    }
                    if (null != _isNullPrefix) { 
                        if (columnName.StartsWith(_isNullPrefix, StringComparison.OrdinalIgnoreCase)) { 
                            continue;
                        } 
                    }

                    // Mutate name if it contains space(s)
                    if (columnName.IndexOf(' ') >= 0) { 
                        columnName = columnName.Replace(' ', '_');
                        isMutatedName = true; 
                    } 

                    // Validate name against regular expression 
                    if (!_parameterNameParser.IsMatch(columnName)) {
                        continue;
                    }
 
                    // Validate name against adjusted max parametername length
                    if (columnName.Length > _adjustedParameterNameMaxLength) { 
                        continue; 
                    }
 
                    _baseParameterNames[i] = columnName;
                    _isMutatedName[i] = isMutatedName;
                }
 
                EliminateConflictingNames();
 
                // Generate names for original- and isNullparameters 
                // no names will be generated if the prefix failed parametername validation
                for (int i = 0; i < schemaRows.Length; i++) { 
                    if (null != _baseParameterNames[i]) {
                        if (null != _originalPrefix) {
                            _originalParameterNames[i] = _originalPrefix + _baseParameterNames[i];
                        } 
                        if (null != _isNullPrefix) {
                            // don't bother generating an 'IsNull' name if it's not used 
                            if (schemaRows[i].AllowDBNull) { 
                                _nullParameterNames[i] = _isNullPrefix + _baseParameterNames[i];
                            } 
                        }
                    }
                }
                ApplyProviderSpecificFormat(); 
                GenerateMissingNames(schemaRows);
            } 
 
            private void SetAndValidateNamePrefixes() {
                if (_parameterNameParser.IsMatch(DefaultIsNullPrefix)) { 
                    _isNullPrefix = DefaultIsNullPrefix;
                }
                else if (_parameterNameParser.IsMatch(AlternativeIsNullPrefix)) {
                    _isNullPrefix = AlternativeIsNullPrefix; 
                }
                else if (_parameterNameParser.IsMatch(AlternativeIsNullPrefix2)) { 
                    _isNullPrefix = AlternativeIsNullPrefix2; 
                }
                else { 
                    _isNullPrefix = null;
                }
                if (_parameterNameParser.IsMatch(DefaultOriginalPrefix)) {
                    _originalPrefix = DefaultOriginalPrefix; 
                }
                else if (_parameterNameParser.IsMatch(AlternativeOriginalPrefix)) { 
                    _originalPrefix = AlternativeOriginalPrefix; 
                }
                else if (_parameterNameParser.IsMatch(AlternativeOriginalPrefix2)) { 
                    _originalPrefix = AlternativeOriginalPrefix2;
                }
                else {
                    _originalPrefix = null; 
                }
            } 
 
            private void ApplyProviderSpecificFormat() {
                for (int i = 0; i < _baseParameterNames.Length; i++) { 
                    if (null != _baseParameterNames[i]) {
                        _baseParameterNames[i] = _dbCommandBuilder.GetParameterName(_baseParameterNames[i]);
                    }
                    if (null != _originalParameterNames[i]) { 
                        _originalParameterNames[i] = _dbCommandBuilder.GetParameterName(_originalParameterNames[i]);
                    } 
                    if (null != _nullParameterNames[i]) { 
                        _nullParameterNames[i] = _dbCommandBuilder.GetParameterName(_nullParameterNames[i]);
                    } 
                }
            }

            private void EliminateConflictingNames() { 
                //
 
 

                for (int i = 0; i < _count - 1; i++) { 
                    string name = _baseParameterNames[i];
                    if (null != name) {
                        for (int j = i + 1; j < _count; j++) {
                            if (ADP.CompareInsensitiveInvariant(name, _baseParameterNames[j])) { 
                                // found duplicate name
                                // the name unchanged name wins 
                                int iMutatedName = _isMutatedName[j] ? j : i; 
                                Debug.Assert(_isMutatedName[iMutatedName], String.Format(CultureInfo.InvariantCulture, "{0} expected to be a mutated name", _baseParameterNames[iMutatedName]));
                                _baseParameterNames[iMutatedName] = null;   // null out the culprit 
                            }
                        }
                    }
                } 
            }
 
            // Generates parameternames that couldn't be generated from columnname 
            internal void GenerateMissingNames(DbSchemaRow[] schemaRows) {
                // foreach name in base names 
                // if base name is null
                //  for base, original and nullnames (null names only if nullable)
                //   do
                //    generate name based on current index 
                //    increment index
                //    search name in base names 
                //   loop while name occures in base names 
                //  end for
                // end foreach 
                string name;
                for (int i = 0; i < _baseParameterNames.Length; i++) {
                    name = _baseParameterNames[i];
                    if (null == name) { 
                        _baseParameterNames[i] = GetNextGenericParameterName();
                        _originalParameterNames[i] = GetNextGenericParameterName(); 
                        // don't bother generating an 'IsNull' name if it's not used 
                        if ((null != schemaRows[i]) && schemaRows[i].AllowDBNull) {
                            _nullParameterNames[i] = GetNextGenericParameterName(); 
                        }
                    }
                }
            } 

            private int GetAdjustedParameterNameMaxLength() { 
                int maxPrefixLength = Math.Max( 
                    (null != _isNullPrefix ? _isNullPrefix.Length : 0),
                    (null != _originalPrefix ? _originalPrefix.Length : 0) 
                    ) + _dbCommandBuilder.GetParameterName("").Length;
                return _dbCommandBuilder.ParameterNameMaxLength - maxPrefixLength;
            }
 
            private string GetNextGenericParameterName() {
                string name; 
                bool nameExist; 
                do {
                    nameExist = false; 
                    _genericParameterCount++;
                    name = _dbCommandBuilder.GetParameterName(_genericParameterCount);
                    for (int i = 0; i < _baseParameterNames.Length; i++) {
                        if (ADP.CompareInsensitiveInvariant(_baseParameterNames[i], name)) { 
                            nameExist = true;
                            break; 
                        } 
                    }
                } while (nameExist); 
                return name;
            }

            internal string GetBaseParameterName(int index) { 
                return (_baseParameterNames[index]);
            } 
            internal string GetOriginalParameterName(int index) { 
                return (_originalParameterNames[index]);
            } 
            internal string GetNullParameterName(int index) {
                return (_nullParameterNames[index]);
            }
        } 

        private const string DeleteFrom          = "DELETE FROM "; 
 
        private const string InsertInto          = "INSERT INTO ";
        private const string DefaultValues       = " DEFAULT VALUES"; 
        private const string Values              = " VALUES ";

        private const string Update              = "UPDATE ";
 
        private const string Set                 = " SET ";
        private const string Where               = " WHERE "; 
        private const string SpaceLeftParenthesis = " ("; 

        private const string Comma               = ", "; 
        private const string Equal               = " = ";
        private const string LeftParenthesis     = "(";
        private const string RightParenthesis    = ")";
        private const string NameSeparator       = "."; 

        private const string IsNull              = " IS NULL"; 
        private const string EqualOne            = " = 1"; 
        private const string And                 = " AND ";
        private const string Or                  = " OR "; 

        private DbDataAdapter _dataAdapter;

        private DbCommand _insertCommand; 
        private DbCommand _updateCommand;
        private DbCommand _deleteCommand; 
 
        private MissingMappingAction _missingMappingAction;
 
        private ConflictOption _conflictDetection = ConflictOption.CompareAllSearchableValues;
        private bool _setAllValues = false;
        private bool _hasPartialPrimaryKey = false;
 
        private DataTable _dbSchemaTable;
        private DbSchemaRow[] _dbSchemaRows; 
        private string[] _sourceColumnNames; 
        private ParameterNames _parameterNames = null;
 
        private string _quotedBaseTableName;

        // quote strings to use around SQL object names
        private CatalogLocation _catalogLocation = CatalogLocation.Start; 
        private string _catalogSeparator = NameSeparator;
        private string _schemaSeparator = NameSeparator; 
        private string _quotePrefix = ""; 
        private string _quoteSuffix = "";
        private string _parameterNamePattern = null; 
        private string _parameterMarkerFormat = null;
        private int    _parameterNameMaxLength = 0;

        protected DbCommandBuilder() : base() { // V1.2.3300 
        }
 
        [ 
        DefaultValueAttribute(ConflictOption.CompareAllSearchableValues),
        ResCategoryAttribute(Res.DataCategory_Update), 
        ResDescriptionAttribute(Res.DbCommandBuilder_ConflictOption),
        ]
        virtual public ConflictOption ConflictOption { // V1.2.3300
            get { 
                return _conflictDetection;
            } 
            set { 
                switch(value) {
                case ConflictOption.CompareAllSearchableValues: 
                case ConflictOption.CompareRowVersion:
                case ConflictOption.OverwriteChanges:
                    _conflictDetection = value;
                    break; 
                default:
                    throw ADP.InvalidConflictOptions(value); 
                } 
            }
        } 

        [
        DefaultValueAttribute(CatalogLocation.Start),
        ResCategoryAttribute(Res.DataCategory_Schema), 
        ResDescriptionAttribute(Res.DbCommandBuilder_CatalogLocation),
        ] 
        virtual public CatalogLocation CatalogLocation { // V1.2.3300, MDAC 79449 
            get {
                return _catalogLocation; 
            }
            set {
                if (null != _dbSchemaTable) {
                    throw ADP.NoQuoteChange(); 
                }
                switch(value) { 
                case CatalogLocation.Start: 
                case CatalogLocation.End:
                    _catalogLocation = value; 
                    break;
                default:
                    throw ADP.InvalidCatalogLocation(value);
                } 
            }
        } 
 
        [
        DefaultValueAttribute(DbCommandBuilder.NameSeparator), 
        ResCategoryAttribute(Res.DataCategory_Schema),
        ResDescriptionAttribute(Res.DbCommandBuilder_CatalogSeparator),
        ]
        virtual public string CatalogSeparator { // V1.2.3300,  MDAC 79449 
            get {
                string catalogSeparator = _catalogSeparator; 
                return (((null != catalogSeparator) && (0 < catalogSeparator.Length)) ? catalogSeparator : NameSeparator); 
            }
            set { 
                if (null != _dbSchemaTable) {
                    throw ADP.NoQuoteChange();
                }
                _catalogSeparator = value; 
            }
        } 
 
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        ResDescriptionAttribute(Res.DbCommandBuilder_DataAdapter),
        ]
        public DbDataAdapter DataAdapter { // V1.2.3300 
            get {
                return _dataAdapter; 
            } 
            set {
                if (_dataAdapter != value) { 
                    RefreshSchema();

                    if (null != _dataAdapter) {
                        // derived should remove event handler from old adapter 
                        SetRowUpdatingHandler(_dataAdapter);
                        _dataAdapter = null; 
                    } 
                    if (null != value) {
                        // derived should add event handler to new adapter 
                        SetRowUpdatingHandler(value);
                        _dataAdapter = value;
                    }
                } 
            }
        } 
 
        internal int ParameterNameMaxLength {
            get { 
                return _parameterNameMaxLength;
            }
        }
 
        internal string ParameterNamePattern {
            get { 
                return _parameterNamePattern; 
            }
        } 

        private string QuotedBaseTableName {
            get {
                return _quotedBaseTableName; 
            }
        } 
 
        [
        DefaultValueAttribute(""), 
        ResCategoryAttribute(Res.DataCategory_Schema),
        ResDescriptionAttribute(Res.DbCommandBuilder_QuotePrefix),
        ]
        virtual public string QuotePrefix { // V1.2.3300, XXXCommandBuilder V1.0.3300 
            get {
                string quotePrefix = _quotePrefix; 
                return ((null != quotePrefix) ? quotePrefix : ADP.StrEmpty); 
            }
            set { 
                if (null != _dbSchemaTable) {
                    throw ADP.NoQuoteChange();
                }
                _quotePrefix = value; 
            }
        } 
 
        [
        DefaultValueAttribute(""), 
        ResCategoryAttribute(Res.DataCategory_Schema),
        ResDescriptionAttribute(Res.DbCommandBuilder_QuoteSuffix),
        ]
        virtual public string QuoteSuffix { // V1.2.3300, XXXCommandBuilder V1.0.3300 
            get {
                string quoteSuffix = _quoteSuffix; 
                return ((null != quoteSuffix) ? quoteSuffix : ADP.StrEmpty); 
            }
            set { 
                if (null != _dbSchemaTable) {
                    throw ADP.NoQuoteChange();
                }
                _quoteSuffix = value; 
            }
        } 
 

        [ 
        DefaultValueAttribute(DbCommandBuilder.NameSeparator),
        ResCategoryAttribute(Res.DataCategory_Schema),
        ResDescriptionAttribute(Res.DbCommandBuilder_SchemaSeparator),
        ] 
        virtual public string SchemaSeparator { // V1.2.3300, MDAC 79449
            get { 
                string schemaSeparator = _schemaSeparator; 
                return (((null != schemaSeparator) && (0 < schemaSeparator.Length)) ? schemaSeparator : NameSeparator);
            } 
            set {
                if (null != _dbSchemaTable) {
                    throw ADP.NoQuoteChange();
                } 
                _schemaSeparator = value;
            } 
        } 

        [ 
        DefaultValueAttribute(false),
        ResCategoryAttribute(Res.DataCategory_Schema),
        ResDescriptionAttribute(Res.DbCommandBuilder_SetAllValues),
        ] 
        public bool SetAllValues {
            get { 
                return _setAllValues; 
            }
            set { 
                _setAllValues = value;
            }
        }
 
        private DbCommand InsertCommand {
            get { 
                return _insertCommand; 
            }
            set { 
                _insertCommand = value;
            }
        }
 
        private DbCommand UpdateCommand {
            get { 
                return _updateCommand; 
            }
            set { 
                _updateCommand = value;
            }
        }
 
        private DbCommand DeleteCommand {
            get { 
                return _deleteCommand; 
            }
            set { 
                _deleteCommand = value;
            }
        }
 
        private void BuildCache(bool closeConnection, DataRow dataRow, bool useColumnsForParameterNames) { // V1.2.3300
            // Don't bother building the cache if it's done already; wait for 
            // the user to call RefreshSchema first. 
            if ((null != _dbSchemaTable) && (!useColumnsForParameterNames || (null != _parameterNames))) {
                return; 
            }
            DataTable schemaTable = null;

            DbCommand srcCommand = GetSelectCommand(); 
            DbConnection connection = srcCommand.Connection;
            if (null == connection) { 
                throw ADP.MissingSourceCommandConnection(); 
            }
 
            try {
                if (0 == (ConnectionState.Open & connection.State)) {
                    connection.Open();
                } 
                else {
                    closeConnection = false; 
                } 

                if (useColumnsForParameterNames) { 
                    DataTable dataTable = connection.GetSchema(DbMetaDataCollectionNames.DataSourceInformation);
                    if (dataTable.Rows.Count == 1) {
                        _parameterNamePattern = dataTable.Rows[0][DbMetaDataColumnNames.ParameterNamePattern] as string;
                        _parameterMarkerFormat = dataTable.Rows[0][DbMetaDataColumnNames.ParameterMarkerFormat] as string; 

                        object oParameterNameMaxLength = dataTable.Rows[0][DbMetaDataColumnNames.ParameterNameMaxLength]; 
                        _parameterNameMaxLength = (oParameterNameMaxLength is int) ? (int)oParameterNameMaxLength : 0; 

                        // note that we protect against errors in the xml file! 
                        if (0 == _parameterNameMaxLength || null == _parameterNamePattern || null == _parameterMarkerFormat) {
                            useColumnsForParameterNames = false;
                        }
                    } 
                    else {
                        Debug.Assert(false, "Rowcount expected to be 1"); 
                        useColumnsForParameterNames = false; 
                    }
                } 
                schemaTable = GetSchemaTable(srcCommand);
            }
            finally {
                if (closeConnection) { 
                    connection.Close();
                } 
            } 

            if (null == schemaTable) { 
                throw ADP.DynamicSQLNoTableInfo();
            }
#if DEBUG
            //if (AdapterSwitches.DbCommandBuilder.TraceVerbose) { 
            //    ADP.TraceDataTable("DbCommandBuilder", schemaTable);
            //} 
#endif 
            BuildInformation(schemaTable);
 
            _dbSchemaTable = schemaTable;

            DbSchemaRow[] schemaRows = _dbSchemaRows;
            string[] srcColumnNames = new string[schemaRows.Length]; 
            for (int i = 0; i < schemaRows.Length; ++i) {
                if (null != schemaRows[i]) { 
                    srcColumnNames[i] = schemaRows[i].ColumnName; 
                }
            } 
            _sourceColumnNames = srcColumnNames;
            if (useColumnsForParameterNames) {
                _parameterNames = new ParameterNames(this, schemaRows);
            } 
            ADP.BuildSchemaTableInfoTableNames(srcColumnNames);
        } 
 
        virtual protected DataTable GetSchemaTable (DbCommand sourceCommand) {
            using (IDataReader dataReader = sourceCommand.ExecuteReader(CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo)){ 
                return dataReader.GetSchemaTable();
            }
        }
 
        private void BuildInformation(DataTable schemaTable) {
            DbSchemaRow[] rows = DbSchemaRow.GetSortedSchemaRows(schemaTable, false); // MDAC 60609 
            if ((null == rows) || (0 == rows.Length)) { 
                throw ADP.DynamicSQLNoTableInfo();
            } 

            string baseServerName = ""; // MDAC 72721, 73599
            string baseCatalogName = "";
            string baseSchemaName = ""; 
            string baseTableName = null;
 
            for (int i = 0; i < rows.Length; ++i) { 
                DbSchemaRow row = rows[i];
                string tableName = row.BaseTableName; 
                if ((null == tableName) || (0 == tableName.Length)) {
                    rows[i] = null;
                    continue;
                } 

                string serverName = row.BaseServerName; 
                string catalogName = row.BaseCatalogName; 
                string schemaName = row.BaseSchemaName;
                if (null == serverName) { 
                    serverName = "";
                }
                if (null == catalogName) {
                    catalogName = ""; 
                }
                if (null == schemaName) { 
                    schemaName = ""; 
                }
                if (null == baseTableName) { 
                    baseServerName = serverName;
                    baseCatalogName = catalogName;
                    baseSchemaName = schemaName;
                    baseTableName = tableName; 
                }
                else if (  (0 != ADP.SrcCompare(baseTableName, tableName)) 
                    || (0 != ADP.SrcCompare(baseSchemaName, schemaName)) 
                    || (0 != ADP.SrcCompare(baseCatalogName, catalogName))
                    || (0 != ADP.SrcCompare(baseServerName, serverName))) { 
                    throw ADP.DynamicSQLJoinUnsupported();
                }
            }
            if (0 == baseServerName.Length) { 
                baseServerName = null;
            } 
            if (0 == baseCatalogName.Length) { 
                baseServerName = null;
                baseCatalogName = null; 
            }
            if (0 == baseSchemaName.Length) {
                baseServerName = null;
                baseCatalogName = null; 
                baseSchemaName = null;
            } 
            if ((null == baseTableName) || (0 == baseTableName.Length)) { 
                throw ADP.DynamicSQLNoTableInfo();
            } 

            CatalogLocation location = CatalogLocation;
            string catalogSeparator = CatalogSeparator;
            string schemaSeparator = SchemaSeparator; 

            string quotePrefix = QuotePrefix; 
            string quoteSuffix = QuoteSuffix; 

            if (!ADP.IsEmpty(quotePrefix) && (-1 != baseTableName.IndexOf(quotePrefix, StringComparison.Ordinal))) { 
                throw ADP.DynamicSQLNestedQuote(baseTableName, quotePrefix);
            }
            if (!ADP.IsEmpty(quoteSuffix) && (-1 != baseTableName.IndexOf(quoteSuffix, StringComparison.Ordinal))) {
                throw ADP.DynamicSQLNestedQuote(baseTableName, quoteSuffix); 
            }
 
            System.Text.StringBuilder builder = new System.Text.StringBuilder(); 
            if (CatalogLocation.Start == location) {
                // MDAC 79449 
                if (null != baseServerName) {
                    builder.Append(ADP.BuildQuotedString(quotePrefix, quoteSuffix, baseServerName));
                    builder.Append(catalogSeparator);
                } 
                if (null != baseCatalogName) {
                    builder.Append(ADP.BuildQuotedString(quotePrefix, quoteSuffix, baseCatalogName)); 
                    builder.Append(catalogSeparator); 
                }
                // 
            }
            if (null != baseSchemaName) {
                builder.Append(ADP.BuildQuotedString(quotePrefix, quoteSuffix, baseSchemaName));
                builder.Append(schemaSeparator); 
            }
            // 
            builder.Append(ADP.BuildQuotedString(quotePrefix, quoteSuffix, baseTableName)); 

            if (CatalogLocation.End == location) { 
                // MDAC 79449
                if (null != baseServerName) {
                    builder.Append(catalogSeparator);
                    builder.Append(ADP.BuildQuotedString(quotePrefix, quoteSuffix, baseServerName)); 
                }
                if (null != baseCatalogName) { 
                    builder.Append(catalogSeparator); 
                    builder.Append(ADP.BuildQuotedString(quotePrefix, quoteSuffix, baseCatalogName));
                } 
            }
            _quotedBaseTableName = builder.ToString();

            _hasPartialPrimaryKey = false; 
            foreach(DbSchemaRow row in rows) {
                if ((null != row) && (row.IsKey || row.IsUnique) && !row.IsLong && !row.IsRowVersion && row.IsHidden) { 
                    _hasPartialPrimaryKey = true; 
                    break;
                } 
            }
            _dbSchemaRows = rows;
        }
 
        private DbCommand BuildDeleteCommand(DataTableMapping mappings, DataRow dataRow) {
            DbCommand command = InitializeCommand(DeleteCommand); 
            StringBuilder builder = new StringBuilder(); 
            int parameterCount  = 0;
 
            Debug.Assert (!ADP.IsEmpty(_quotedBaseTableName), "no table name");

            builder.Append(DeleteFrom);
            builder.Append(QuotedBaseTableName); 

            parameterCount = BuildWhereClause(mappings, dataRow, builder, command, parameterCount, false); 
 
            command.CommandText = builder.ToString();
 
            RemoveExtraParameters(command, parameterCount);
            DeleteCommand = command;
            return command;
        } 

        private DbCommand BuildInsertCommand(DataTableMapping mappings, DataRow dataRow) { 
            DbCommand command = InitializeCommand(InsertCommand); 
            StringBuilder builder = new StringBuilder();
            int             parameterCount  = 0; 
            string          nextSeparator   = SpaceLeftParenthesis;

            Debug.Assert (!ADP.IsEmpty(_quotedBaseTableName), "no table name");
 
            builder.Append(InsertInto);
            builder.Append(QuotedBaseTableName); 
 
            // search for the columns in that base table, to be the column clause
            DbSchemaRow[] schemaRows = _dbSchemaRows; 
            string[] parameterName = new string[schemaRows.Length];
            for (int i = 0; i < schemaRows.Length; ++i) {
                DbSchemaRow row = schemaRows[i];
 
                if ( (null == row) || (0 == row.BaseColumnName.Length) || !IncludeInInsertValues(row) )
                    continue; 
 
                object currentValue = null;
                string sourceColumn = _sourceColumnNames[i]; 

                // If we're building a statement for a specific row, then check the
                // values to see whether the column should be included in the insert
                // statement or not 
                if ((null != mappings) && (null != dataRow)) {
                    DataColumn dataColumn = GetDataColumn(sourceColumn, mappings, dataRow); 
 
                    if (null == dataColumn)
                        continue; 

                    // Don't bother inserting if the column is readonly in both the data
                    // set and the back end.
                    if (row.IsReadOnly && dataColumn.ReadOnly) 
                        continue;
 
                    currentValue = GetColumnValue(dataRow, dataColumn, DataRowVersion.Current); 

                    // If the value is null, and the column doesn't support nulls, then 
                    // the user is requesting the server-specified default value, so don't
                    // include it in the set-list.
                    if ( !row.AllowDBNull && (null == currentValue || Convert.IsDBNull(currentValue)) )
                        continue; 
                }
 
                builder.Append(nextSeparator); 
                nextSeparator = Comma;
                builder.Append(QuotedColumn(row.BaseColumnName)); 

                parameterName[parameterCount] = CreateParameterForValue(
                    command,
                    GetBaseParameterName(i), 
                    sourceColumn,
                    DataRowVersion.Current, 
                    parameterCount, 
                    currentValue,
                    row, StatementType.Insert, false 
                    );
                parameterCount++;
            }
 
            if (0 == parameterCount)
                builder.Append(DefaultValues); 
            else { 
                builder.Append(RightParenthesis);
                builder.Append(Values); 
                builder.Append(LeftParenthesis);

                builder.Append(parameterName[0]);
                for (int i = 1; i < parameterCount; ++i) { 
                    builder.Append(Comma);
                    builder.Append(parameterName[i]); 
                } 

                builder.Append(RightParenthesis); 
            }

            command.CommandText = builder.ToString();
 
            RemoveExtraParameters(command, parameterCount);
            InsertCommand = command; 
            return command; 
        }
 
        private DbCommand BuildUpdateCommand(DataTableMapping mappings, DataRow dataRow) {
            DbCommand command = InitializeCommand(UpdateCommand);
            StringBuilder builder = new StringBuilder();
            string nextSeparator = Set; 
            int parameterCount  = 0;
 
            Debug.Assert (!ADP.IsEmpty(_quotedBaseTableName), "no table name"); 

            builder.Append(Update); 
            builder.Append(QuotedBaseTableName);

            // search for the columns in that base table, to build the set clause
            DbSchemaRow[] schemaRows = _dbSchemaRows; 
            for (int i = 0; i < schemaRows.Length; ++i) {
                DbSchemaRow row = schemaRows[i]; 
 
                if ((null == row) || (0 == row.BaseColumnName.Length) || !IncludeInUpdateSet(row))
                    continue; 

                object currentValue = null;
                string sourceColumn = _sourceColumnNames[i];
 
                // If we're building a statement for a specific row, then check the
                // values to see whether the column should be included in the update 
                // statement or not 
                if ((null != mappings) && (null != dataRow)) {
                    DataColumn  dataColumn = GetDataColumn(sourceColumn, mappings, dataRow); 

                    if (null == dataColumn)
                        continue;
 
                    // Don't bother updating if the column is readonly in both the data
                    // set and the back end. 
                    if (row.IsReadOnly && dataColumn.ReadOnly) 
                        continue;
 
                    // Unless specifically directed to do so, we will not automatically update
                    // a column with it's original value, which means that we must determine
                    // whether the value has changed locally, before we send it up.
                    currentValue = GetColumnValue(dataRow, dataColumn, DataRowVersion.Current); 

                    if (!SetAllValues) { 
                        object originalValue = GetColumnValue(dataRow, dataColumn, DataRowVersion.Original); 

                        if ((originalValue == currentValue) 
                            || ((null != originalValue) && originalValue.Equals(currentValue))) {
                            continue;
                        }
                    } 
                }
 
                builder.Append(nextSeparator); 
                nextSeparator = Comma;
 
                builder.Append(QuotedColumn(row.BaseColumnName));
                builder.Append(Equal);
                builder.Append(
                    CreateParameterForValue( 
                        command,
                        GetBaseParameterName(i), 
                        sourceColumn, 
                        DataRowVersion.Current,
                        parameterCount, 
                        currentValue,
                        row, StatementType.Update, false
                    )
                ); 
                parameterCount++;
            } 
 
            // It is an error to attempt an update when there's nothing to update;
            bool skipRow = (0 == parameterCount); 

            parameterCount = BuildWhereClause(mappings, dataRow, builder, command, parameterCount, true);

            command.CommandText = builder.ToString(); 

            RemoveExtraParameters(command, parameterCount); 
            UpdateCommand = command; 
            return (skipRow) ? null : command;
        } 

        private int BuildWhereClause(
            DataTableMapping mappings,
            DataRow          dataRow, 
            StringBuilder    builder,
            DbCommand        command, 
            int              parameterCount, 
            bool             isUpdate
            ) { 
            string  beginNewCondition = string.Empty;
            int     whereCount = 0;

            builder.Append(Where); 
            builder.Append(LeftParenthesis);
 
            DbSchemaRow[] schemaRows = _dbSchemaRows; 
            for (int i = 0; i < schemaRows.Length; ++i) {
                DbSchemaRow row = schemaRows[i]; 

                if ((null == row) || (0 == row.BaseColumnName.Length) || !IncludeInWhereClause(row, isUpdate)) {
                    continue;
                } 
                builder.Append(beginNewCondition);
                beginNewCondition = And; 
 
                object value = null;
                string sourceColumn = _sourceColumnNames[i]; 
                string baseColumnName = QuotedColumn(row.BaseColumnName);

                if ((null != mappings) && (null != dataRow))
                    value = GetColumnValue(dataRow, sourceColumn, mappings, DataRowVersion.Original); 

                if (!row.AllowDBNull) { 
                    //  ( = ?) 
                    builder.Append(LeftParenthesis);
                    builder.Append(baseColumnName); 
                    builder.Append(Equal);
                    builder.Append(
                        CreateParameterForValue(
                            command, 
                            GetOriginalParameterName(i),
                            sourceColumn, 
                            DataRowVersion.Original, 
                            parameterCount,
                            value, 
                            row, (isUpdate ? StatementType.Update : StatementType.Delete), true
                        )
                    );
                    parameterCount++; 
                    builder.Append(RightParenthesis);
                } 
                else { 
                    //  ((? = 1 AND  IS NULL) OR ( = ?))
                    builder.Append(LeftParenthesis); 

                    builder.Append(LeftParenthesis);
                    builder.Append(
                        CreateParameterForNullTest( 
                            command,
                            GetNullParameterName(i), 
                            sourceColumn, 
                            DataRowVersion.Original,
                            parameterCount, 
                            value,
                            row, (isUpdate ? StatementType.Update : StatementType.Delete), true
                        )
                    ); 
                    parameterCount++;
                    builder.Append(EqualOne); 
                    builder.Append(And); 
                    builder.Append(baseColumnName);
                    builder.Append(IsNull); 
                    builder.Append(RightParenthesis);

                    builder.Append(Or);
 
                    builder.Append(LeftParenthesis);
                    builder.Append(baseColumnName); 
                    builder.Append(Equal); 
                    builder.Append(
                        CreateParameterForValue( 
                            command,
                            GetOriginalParameterName(i),
                            sourceColumn,
                            DataRowVersion.Original, 
                            parameterCount,
                            value, 
                            row, (isUpdate ? StatementType.Update : StatementType.Delete), true 
                        )
                    ); 
                    parameterCount++;
                    builder.Append(RightParenthesis);

                    builder.Append(RightParenthesis); 
                }
 
                if (IncrementWhereCount(row)) { 
                    whereCount++;
                } 
            }

            builder.Append(RightParenthesis);
 
            if (0 == whereCount) {
                if (isUpdate) { 
                    if (ConflictOption.CompareRowVersion == ConflictOption) { 
                        throw ADP.DynamicSQLNoKeyInfoRowVersionUpdate();
                    } 
                    throw ADP.DynamicSQLNoKeyInfoUpdate();
                }
                else {
                    if (ConflictOption.CompareRowVersion == ConflictOption) { 
                        throw ADP.DynamicSQLNoKeyInfoRowVersionDelete();
                    } 
                    throw ADP.DynamicSQLNoKeyInfoDelete(); 
                }
            } 
            return parameterCount;
        }

        private string CreateParameterForNullTest( 
            DbCommand       command,
            string          parameterName, 
            string          sourceColumn, 
            DataRowVersion  version,
            int             parameterCount, 
            object          value,
            DbSchemaRow     row,
            StatementType   statementType,
            bool            whereClause 
            ) {
            DbParameter p = GetNextParameter(command, parameterCount); 
 
            Debug.Assert(!ADP.IsEmpty(sourceColumn), "empty source column");
            if (null == parameterName) { 
                p.ParameterName = GetParameterName(1 + parameterCount);
            }
            else {
                p.ParameterName = parameterName; 
            }
            p.Direction     = ParameterDirection.Input; 
            p.SourceColumn  = sourceColumn; 
            p.SourceVersion = version;
            p.SourceColumnNullMapping = true; 
            p.Value         = value;
            p.Size          = 0; // don't specify parameter.Size so that we don't silently truncate to the metadata size

            ApplyParameterInfo(p, row.DataRow, statementType, whereClause); 

            p.DbType        = DbType.Int32; 
            p.Value         = ADP.IsNull(value) ? DbDataAdapter.ParameterValueNullValue : DbDataAdapter.ParameterValueNonNullValue; 

            if (!command.Parameters.Contains(p)) { 
                command.Parameters.Add(p);
            }

            if (null == parameterName) { 
                return GetParameterPlaceholder(1 + parameterCount);
            } 
            else { 
                Debug.Assert(null != _parameterNames, "How can we have a parameterName without a _parameterNames collection?");
                Debug.Assert(null != _parameterMarkerFormat, "How can we have a _parameterNames collection but no _parameterMarkerFormat?"); 

                return String.Format(CultureInfo.InvariantCulture, _parameterMarkerFormat, parameterName);
            }
        } 

        private string CreateParameterForValue( 
            DbCommand       command, 
            string          parameterName,
            string          sourceColumn, 
            DataRowVersion  version,
            int             parameterCount,
            object          value,
            DbSchemaRow     row, 
            StatementType   statementType,
            bool            whereClause 
            ) { 
            DbParameter p = GetNextParameter(command, parameterCount);
 
            if (null == parameterName) {
                p.ParameterName = GetParameterName(1 + parameterCount);
            }
            else { 
                p.ParameterName = parameterName;
            } 
            p.Direction     = ParameterDirection.Input; 
            p.SourceColumn  = sourceColumn;
            p.SourceVersion = version; 
            p.SourceColumnNullMapping = false;
            p.Value         = value;
            p.Size          = 0; // don't specify parameter.Size so that we don't silently truncate to the metadata size
 
            ApplyParameterInfo(p, row.DataRow, statementType, whereClause);
 
            if (!command.Parameters.Contains(p)) { 
                command.Parameters.Add(p);
            } 

            if (null == parameterName) {
                return GetParameterPlaceholder(1 + parameterCount);
            } 
            else {
                Debug.Assert(null != _parameterNames, "How can we have a parameterName without a _parameterNames collection?"); 
                Debug.Assert(null != _parameterMarkerFormat, "How can we have a _parameterNames collection but no _parameterMarkerFormat?"); 

                return String.Format(CultureInfo.InvariantCulture, _parameterMarkerFormat, parameterName); 
            }
        }

        override protected void Dispose(bool disposing) { // V1.2.3300, XXXCommandBuilder V1.0.3300 
            // MDAC 65459
            if (disposing) { 
                // release mananged objects 
                DataAdapter = null;
            } 
            //release unmanaged objects

            base.Dispose(disposing); // notify base classes
        } 

        private DataTableMapping GetTableMapping(DataRow dataRow ) { 
            DataTableMapping tableMapping = null; 
            if (null != dataRow) {
                DataTable dataTable = dataRow.Table; 
                if (null != dataTable) {
                    DbDataAdapter adapter = DataAdapter;
                    if (null != adapter) {
                        tableMapping = adapter.GetTableMapping(dataTable); 
                    }
                    else { 
                        string tableName = dataTable.TableName; 
                        tableMapping = new DataTableMapping(tableName, tableName);
                    } 
                }
            }
            return tableMapping;
        } 

        private string GetBaseParameterName(int index) { 
            if (null != _parameterNames) { 
                return (_parameterNames.GetBaseParameterName(index));
            } 
            else {
                return null;
            }
        } 
        private string GetOriginalParameterName(int index) {
            if (null != _parameterNames) { 
                return (_parameterNames.GetOriginalParameterName(index)); 
            }
            else { 
                return null;
            }
        }
        private string GetNullParameterName(int index) { 
            if (null != _parameterNames) {
                return (_parameterNames.GetNullParameterName(index)); 
            } 
            else {
                return null; 
            }
        }

        private DbCommand GetSelectCommand() { // V1.2.3300 
            DbCommand select = null;
            DbDataAdapter adapter = DataAdapter; 
            if (null != adapter) { 
                if (0 == _missingMappingAction) {
                    _missingMappingAction = adapter.MissingMappingAction; 
                }
                select = (DbCommand)adapter.SelectCommand;
            }
            if (null == select) { 
                throw ADP.MissingSourceCommand();
            } 
            return select; 
        }
 
        public DbCommand GetInsertCommand() { // V1.2.3300, XXXCommandBuilder V1.0.3300
            return GetInsertCommand((DataRow)null, false);
        }
 
        public DbCommand GetInsertCommand(bool useColumnsForParameterNames) {
            return GetInsertCommand((DataRow)null, useColumnsForParameterNames); 
        } 
        internal DbCommand GetInsertCommand(DataRow dataRow, bool useColumnsForParameterNames) {
            BuildCache(true, dataRow, useColumnsForParameterNames); 
            BuildInsertCommand(GetTableMapping(dataRow), dataRow);
            return InsertCommand;
        }
 
        public DbCommand GetUpdateCommand() { // V1.2.3300, XXXCommandBuilder V1.0.3300
            return GetUpdateCommand((DataRow)null, false); 
        } 
        public DbCommand GetUpdateCommand(bool useColumnsForParameterNames) {
            return GetUpdateCommand((DataRow)null, useColumnsForParameterNames); 
        }
        internal DbCommand GetUpdateCommand(DataRow dataRow, bool useColumnsForParameterNames) {
            BuildCache(true, dataRow, useColumnsForParameterNames);
            BuildUpdateCommand(GetTableMapping(dataRow), dataRow); 
            return UpdateCommand;
        } 
 
        public DbCommand GetDeleteCommand() { // V1.2.3300, XXXCommandBuilder V1.0.3300
            return GetDeleteCommand((DataRow)null, false); 
        }
        public DbCommand GetDeleteCommand(bool useColumnsForParameterNames) {
            return GetDeleteCommand((DataRow)null, useColumnsForParameterNames);
        } 
        internal DbCommand GetDeleteCommand(DataRow dataRow, bool useColumnsForParameterNames) {
            BuildCache(true, dataRow, useColumnsForParameterNames); 
            BuildDeleteCommand(GetTableMapping(dataRow), dataRow); 
            return DeleteCommand;
        } 

        private object GetColumnValue(DataRow row, String columnName, DataTableMapping mappings, DataRowVersion version) {
           return GetColumnValue(row, GetDataColumn(columnName, mappings, row), version);
        } 

        private object GetColumnValue(DataRow row, DataColumn column, DataRowVersion  version) { 
            object value = null; 
            if (null != column) {
                value = row[column, version]; 
            }
            return value;
        }
 
        private DataColumn GetDataColumn(string columnName, DataTableMapping tablemapping, DataRow row) {
            DataColumn column = null; 
            if (!ADP.IsEmpty(columnName)) { 
                column = tablemapping.GetDataColumn(columnName, null, row.Table, _missingMappingAction, MissingSchemaAction.Error);
            } 
            return column;
        }

        static private DbParameter GetNextParameter(DbCommand command, int pcount) { 
            DbParameter p;
            if (pcount < command.Parameters.Count) { 
                p = command.Parameters[pcount]; 
            }
            else { 
                p = command.CreateParameter();
                /*if (null == p) {
                    //
*/ 
            }
            Debug.Assert(null != p, "null CreateParameter"); 
            return p; 
        }
 
        private bool IncludeInInsertValues(DbSchemaRow row) {
            return (!row.IsAutoIncrement && !row.IsHidden && !row.IsExpression && !row.IsRowVersion);
        }
 
        private bool IncludeInUpdateSet(DbSchemaRow row) {
            return (!row.IsAutoIncrement && !row.IsRowVersion && !row.IsHidden); 
        } 

        private bool IncludeInWhereClause(DbSchemaRow row, bool isUpdate) { 
            bool flag = IncrementWhereCount(row);
            if (flag && row.IsHidden) { // MDAC 52564
                if (ConflictOption.CompareRowVersion == ConflictOption) {
                    throw ADP.DynamicSQLNoKeyInfoRowVersionUpdate(); 
                }
                throw ADP.DynamicSQLNoKeyInfoUpdate(); 
            } 
            if (!flag && (ConflictOption.CompareAllSearchableValues == ConflictOption)) {
                // include other searchable values 
                flag = !row.IsLong && !row.IsRowVersion && !row.IsHidden;
            }
            return flag;
        } 

        private bool IncrementWhereCount(DbSchemaRow row) { 
            ConflictOption value = ConflictOption; 
            switch(value) {
            case ConflictOption.CompareAllSearchableValues: 
            case ConflictOption.OverwriteChanges:
                // find the primary key
                return (row.IsKey || row.IsUnique) && !row.IsLong && !row.IsRowVersion;
            case ConflictOption.CompareRowVersion: 
                // or the row version
                return (((row.IsKey || row.IsUnique) && !_hasPartialPrimaryKey) || row.IsRowVersion) && !row.IsLong; 
            default: 
                throw ADP.InvalidConflictOptions(value);
            } 
        }

        virtual protected DbCommand InitializeCommand(DbCommand command) { // V1.2.3300
            if (null == command) { 
                DbCommand select = GetSelectCommand();
                command = select.Connection.CreateCommand(); 
                /*if (null == command) { 
                    //
*/ 

                // the following properties are only initialized when the object is created
                // all other properites are reinitialized on every row
                /*command.Connection = select.Connection;*/ // initialized by CreateCommand 
                command.CommandTimeout = select.CommandTimeout;
                command.Transaction = select.Transaction; 
            } 
            command.CommandType      = CommandType.Text;
            command.UpdatedRowSource = UpdateRowSource.None; // no select or output parameters expected 
            return command;
        }

        private string QuotedColumn(string column) { 
            return ADP.BuildQuotedString(QuotePrefix, QuoteSuffix, column);
        } 
 
        public virtual string QuoteIdentifier(string unquotedIdentifier ) {
 
        throw ADP.NotSupported();
        }

        virtual public void RefreshSchema() { // V1.2.3300, XXXCommandBuilder V1.0.3300 
            _dbSchemaTable = null;
            _dbSchemaRows = null; 
            _sourceColumnNames = null; 
            _quotedBaseTableName = null;
 
            DbDataAdapter adapter = DataAdapter;
            if (null != adapter) { // MDAC 66016
                if (InsertCommand == adapter.InsertCommand) {
                    adapter.InsertCommand = null; 
                }
                if (UpdateCommand == adapter.UpdateCommand) { 
                    adapter.UpdateCommand = null; 
                }
                if (DeleteCommand == adapter.DeleteCommand) { 
                    adapter.DeleteCommand = null;
                }
            }
            DbCommand command; 
            if (null != (command = InsertCommand)) {
                command.Dispose(); 
            } 
            if (null != (command = UpdateCommand)) {
                command.Dispose(); 
            }
            if (null != (command = DeleteCommand)) {
                command.Dispose();
            } 
            InsertCommand = null;
            UpdateCommand = null; 
            DeleteCommand = null; 
        }
 
        static private void RemoveExtraParameters(DbCommand command, int usedParameterCount) {
            for (int i = command.Parameters.Count-1; i >= usedParameterCount; --i) {
                command.Parameters.RemoveAt(i);
            } 
        }
 
        protected void RowUpdatingHandler(RowUpdatingEventArgs rowUpdatingEvent) { 
            if (null == rowUpdatingEvent) {
                throw ADP.ArgumentNull("rowUpdatingEvent"); 
            }
            try {
                if (UpdateStatus.Continue == rowUpdatingEvent.Status) {
                    StatementType stmtType = rowUpdatingEvent.StatementType; 
                    DbCommand command = (DbCommand)rowUpdatingEvent.Command;
 
                    if (null != command) { 
                        switch(stmtType) {
                        case StatementType.Select: 
                            Debug.Assert(false, "how did we get here?");
                            return; // don't mess with it
                        case StatementType.Insert:
                            command = InsertCommand; 
                            break;
                        case StatementType.Update: 
                            command = UpdateCommand; 
                            break;
                        case StatementType.Delete: 
                            command = DeleteCommand;
                            break;
                        default:
                            throw ADP.InvalidStatementType(stmtType); 
                        }
 
                        if (command != rowUpdatingEvent.Command) { 
                            command = (DbCommand)rowUpdatingEvent.Command;
                            if ((null != command) && (null == command.Connection)) { // MDAC 87649 
                                DbDataAdapter adapter = DataAdapter;
                                DbCommand select = ((null != adapter) ? ((DbCommand)adapter.SelectCommand) : null);
                                if (null != select) {
                                    command.Connection = (DbConnection)select.Connection; 

                                } 
                            } 
                            // user command, not a command builder command
                        } 
                        else command = null;
                    }
                    if (null == command) {
                        RowUpdatingHandlerBuilder(rowUpdatingEvent); 
                    }
                 } 
            } 
            catch(Exception e) {
                // 
                if (!ADP.IsCatchableExceptionType(e)) {
                    throw;
                }
 
                ADP.TraceExceptionForCapture(e);
 
                rowUpdatingEvent.Status = UpdateStatus.ErrorsOccurred; 
                rowUpdatingEvent.Errors = e;
            } 
        }

        private void RowUpdatingHandlerBuilder(RowUpdatingEventArgs rowUpdatingEvent) {
            // MDAC 58710 - unable to tell Update method that Event opened connection and Update needs to close when done 
            // HackFix - the Update method will close the connection if command was null and returned command.Connection is same as SelectCommand.Connection
            DataRow datarow = rowUpdatingEvent.Row; 
            BuildCache(false, datarow, false); 

            DbCommand command; 
            switch(rowUpdatingEvent.StatementType) {
            case StatementType.Insert:
                command = BuildInsertCommand(rowUpdatingEvent.TableMapping, datarow);
                break; 
            case StatementType.Update:
                command = BuildUpdateCommand(rowUpdatingEvent.TableMapping, datarow); 
                break; 
            case StatementType.Delete:
                command = BuildDeleteCommand(rowUpdatingEvent.TableMapping, datarow); 
                break;
#if DEBUG
            case StatementType.Select:
                Debug.Assert(false, "how did we get here?"); 
                goto default;
#endif 
            default: 
                throw ADP.InvalidStatementType(rowUpdatingEvent.StatementType);
            } 
            if (null == command) {
                if (null != datarow) {
                    datarow.AcceptChanges();
                } 
                rowUpdatingEvent.Status = UpdateStatus.SkipCurrentRow;
            } 
            rowUpdatingEvent.Command = command; 
        }
 
         public virtual string UnquoteIdentifier(string quotedIdentifier ) {
            throw ADP.NotSupported();
        }
 
        abstract protected void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause); // V1.2.3300
        abstract protected string GetParameterName(int parameterOrdinal); // V1.2.3300 
        abstract protected string GetParameterName(string parameterName); 
        abstract protected string GetParameterPlaceholder(int parameterOrdinal); // V1.2.3300
        abstract protected void SetRowUpdatingHandler(DbDataAdapter adapter); // V1.2.3300 


        //
 

 
        static internal string[] ParseProcedureName(string name, string quotePrefix, string quoteSuffix) { 
            // Procedure may consist of up to four parts:
            // 0) Server 
            // 1) Catalog
            // 2) Schema
            // 3) ProcedureName
            // 
            // Parse the string into four parts, allowing the last part to contain '.'s.
            // If less than four period delimited parts, use the parts from procedure backwards. 
            // 
            const string Separator = ".";
 
            string[] qualifiers = new string[4];
            if (!ADP.IsEmpty(name)) {
                bool useQuotes = !ADP.IsEmpty(quotePrefix) && !ADP.IsEmpty(quoteSuffix);
 
                int currentPos = 0, parts;
                for(parts = 0; (parts < qualifiers.Length) && (currentPos < name.Length); ++parts) { 
                    int startPos = currentPos; 

                    // does the part begin with a quotePrefix? 
                    if (useQuotes && (name.IndexOf(quotePrefix, currentPos, quotePrefix.Length, StringComparison.Ordinal) == currentPos)) {
                        currentPos += quotePrefix.Length; // move past the quotePrefix

                        // search for the quoteSuffix (or end of string) 
                        while (currentPos < name.Length) {
                            currentPos = name.IndexOf(quoteSuffix, currentPos, StringComparison.Ordinal); 
                            if (currentPos < 0) { 
                                // error condition, no quoteSuffix
                                currentPos = name.Length; 
                                break;
                            }
                            else {
                                currentPos += quoteSuffix.Length; // move past the quoteSuffix 

                                // is this a double quoteSuffix? 
                                if ((currentPos < name.Length) && (name.IndexOf(quoteSuffix, currentPos, quoteSuffix.Length, StringComparison.Ordinal) == currentPos)) { 
                                    // a second quoteSuffix, continue search for terminating quoteSuffix
                                    currentPos += quoteSuffix.Length; // move past the second quoteSuffix 
                                }
                                else {
                                    // found the terminating quoteSuffix
                                    break; 
                                }
                            } 
                        } 
                    }
 
                    // search for separator (either no quotePrefix or already past quoteSuffix)
                    if (currentPos < name.Length) {
                        currentPos = name.IndexOf(Separator, currentPos, StringComparison.Ordinal);
                        if ((currentPos < 0) || (parts == qualifiers.Length-1)) { 
                            // last part that can be found
                            currentPos = name.Length; 
                        } 
                    }
 
                    qualifiers[parts] = name.Substring(startPos, currentPos-startPos);
                    currentPos += Separator.Length;
                }
 
                // allign the qualifiers if we had less than MaxQualifiers
                for(int j = qualifiers.Length-1; 0 <= j; --j) { 
                    qualifiers[j] = ((0 < parts) ? qualifiers[--parts] : null); 
                }
            } 
            return qualifiers;
        }
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK