예제 #1
0
        static internal DBSchemaRow[] GetSortedSchemaRows(DataTable dataTable)                    // MDAC 60609
        {
            DataColumn sortindex = new DataColumn("SchemaMapping Unsorted Index", typeof(Int32)); // MDAC 67050

            dataTable.Columns.Add(sortindex);
            int count = dataTable.Rows.Count;

            for (int i = 0; i < count; ++i)
            {
                dataTable.Rows[i][sortindex] = i;
            }
            ;
            DBSchemaTable schemaTable = new DBSchemaTable(dataTable);

            const DataViewRowState rowStates = DataViewRowState.Unchanged | DataViewRowState.Added | DataViewRowState.ModifiedCurrent;

            DataRow[] dataRows = dataTable.Select(null, "ColumnOrdinal ASC", rowStates);
            Debug.Assert(null != dataRows, "GetSchemaRows: unexpected null dataRows");

            DBSchemaRow[] schemaRows = new DBSchemaRow[dataRows.Length];

            for (int i = 0; i < dataRows.Length; ++i)
            {
                schemaRows[i] = new DBSchemaRow(schemaTable, dataRows[i]);
            }
            return(schemaRows);
        }
예제 #2
0
 private bool IncludeForDeleteWhereClause(DBSchemaRow row)   // MDAC 74213
 {
     if (IsBehavior(CommandBuilderBehavior.UseRowVersionInDeleteWhereClause))
     {
         return((row.IsRowVersion || row.IsKey || row.IsUnique) && !row.IsLong && !row.IsHidden);
     }
     return((IsNotBehavior(CommandBuilderBehavior.PrimaryKeyOnlyDeleteWhereClause) || row.IsKey || row.IsUnique) &&
            !row.IsLong && (row.IsKey || !row.IsRowVersion) && !row.IsHidden);
 }
예제 #3
0
 private bool IncludeForUpdateWhereClause(DBSchemaRow row)
 {
     // @devnote: removed IsRowVersion so that MS SQL timestamp columns aren't included in UPDATE WHERE clause
     if (IsBehavior(CommandBuilderBehavior.UseRowVersionInUpdateWhereClause))
     {
         return((row.IsRowVersion || row.IsKey || row.IsUnique) && !row.IsLong && !row.IsHidden);
     }
     return((IsNotBehavior(CommandBuilderBehavior.PrimaryKeyOnlyUpdateWhereClause) || row.IsKey || row.IsUnique) &&
            !row.IsLong && (row.IsKey || !row.IsRowVersion) && !row.IsHidden);
 }
예제 #4
0
        private void ApplyParameterInfo(OleDbParameter parameter, int pcount, DBSchemaRow row)
        {
            parameter.OleDbType  = (OleDbType)row.ProviderType;
            parameter.IsNullable = row.AllowDBNull;
            parameter.Precision  = (byte)row.Precision;
            parameter.Scale      = (byte)row.Scale;
            parameter.Size       = 0; //don't specify parameter.Size so that we don't silently truncate to the metadata size
#if DEBUG
            if (AdapterSwitches.OleDbSql.TraceVerbose)
            {
                ADP.Trace_Parameter("OleDbParameter", parameter);
            }
#endif
        }
예제 #5
0
        private void ApplyParameterInfo(SqlParameter parameter, int pcount, DBSchemaRow row)
        {
            parameter.SqlDbType  = (SqlDbType)row.ProviderType;
            parameter.IsNullable = row.AllowDBNull;
            // MDAC 72662.  Do not set precision or scale if values are default of 0xff (unspecified, or do not apply).
            if ((byte)row.Precision != 0xff)
            {
                parameter.Precision = (byte)row.Precision;
            }
            if ((byte)row.Scale != 0xff)
            {
                parameter.Scale = (byte)row.Scale;
            }
            parameter.Size = 0; //don't specify parameter.Size so that we don't silently truncate to the metadata size
#if DEBUG
            if (AdapterSwitches.OleDbSql.TraceVerbose)
            {
                ADP.Trace_Parameter("SqlParameter", parameter);
            }
#endif
        }
예제 #6
0
        private IDbCommand BuildUpdateCommand(DataTableMapping mappings, DataRow dataRow)
        {
            if (ADP.IsEmpty(this.quotedBaseTableName))
            {
                return(null);
            }
            IDbCommand cmd = BuildNewCommand(this.updateCommand);

            // count the columns for the @p, key count, ?
            int pcount      = 1; // @p1, @p2, ...
            int columnCount = 0;
            int valueCount  = 0;
            int setCount    = 0;

            StringBuilder builder = new StringBuilder();

            builder.Append("UPDATE ");
            builder.Append(QuotedBaseTableName);
            builder.Append(" SET ");

            // search for the columns in that base table, to build the set clause
            int length = this.dbSchemaRows.Length;

            for (int i = 0; i < length; ++i)
            {
                DBSchemaRow row = this.dbSchemaRows[i];
                if ((null == row) || (0 == row.BaseColumnName.Length) || ExcludeFromUpdateSet(row))
                {
                    continue;
                }
                columnCount++;

                object value        = null;
                string sourceColumn = this.sourceColumnNames[i];  // MDAC 60079
                if ((null != mappings) && (null != dataRow))
                {
                    value = GetParameterUpdateValue(sourceColumn, mappings, dataRow, row.IsReadOnly); // MDAC 61424
                    if (null == value)                                                                // unspecified values are skipped
                    {
                        if (row.IsReadOnly)                                                           // MDAC 68339
                        {
                            columnCount--;
                        }
                        continue;
                    }
                }
                if (0 < valueCount)
                {
                    builder.Append(" , ");
                }

                builder.Append(QuotedColumn(row.BaseColumnName));
                AppendParameterText(builder, pcount);

                IDataParameter p = GetNextParameter(cmd, valueCount);
                p.ParameterName = "@p" + pcount.ToString();
                p.Direction     = ParameterDirection.Input;
                p.SourceColumn  = sourceColumn;
                p.SourceVersion = DataRowVersion.Current;
                p.Value         = value;

                if (p is OleDbParameter)
                {
                    ApplyParameterInfo((OleDbParameter)p, pcount, row);
                }
                else if (p is SqlParameter)
                {
                    ApplyParameterInfo((SqlParameter)p, pcount, row);
                }
                else if (p is OdbcParameter)
                {
                    ApplyParameterInfo((OdbcParameter)p, pcount, row);
                }
                if (!cmd.Parameters.Contains(p))
                {
                    cmd.Parameters.Add(p);
                }
                pcount++;
                valueCount++;
            }
            setCount = valueCount;
            builder.Append(" WHERE ( ");

            // search the columns again to build the where clause with optimistic concurrency
            string andclause = "";
            int    whereCount = 0;
            string nullWhereParameter = null, nullWhereSourceColumn = null;

            for (int i = 0; i < length; ++i)
            {
                DBSchemaRow row = this.dbSchemaRows[i];

                if ((null == row) || (0 == row.BaseColumnName.Length) || !IncludeForUpdateWhereClause(row))
                {
                    continue;
                }
                builder.Append(andclause);
                andclause = CommandBuilder.AndClause;

                object value        = null;
                string sourceColumn = this.sourceColumnNames[i]; // MDAC 60079
                if ((null != mappings) && (null != dataRow))
                {
                    value = GetParameterValue(sourceColumn, mappings, dataRow, DataRowVersion.Original);
                }

                bool   pkey = IsPKey(row);
                string backendColumnName = QuotedColumn(row.BaseColumnName);
                if (pkey)
                {
                    if (Convert.IsDBNull(value))
                    {
                        builder.Append(String.Format(WhereClausepn, backendColumnName));
                    }
                    else if (this.namedParameters)
                    {
                        builder.Append(String.Format(WhereClause1p, backendColumnName, pcount));
                    }
                    else
                    {
                        builder.Append(String.Format(WhereClause2p, backendColumnName));
                    }
                }
                else if (this.namedParameters)
                {
                    builder.Append(String.Format(WhereClause1, backendColumnName, pcount, 1 + pcount));
                }
                else
                {
                    builder.Append(String.Format(WhereClause2, backendColumnName));
                }

                if (!pkey || !Convert.IsDBNull(value))
                {
                    IDataParameter p = GetNextParameter(cmd, valueCount); // first parameter value
                    p.ParameterName = "@p" + pcount.ToString();
                    p.Direction     = ParameterDirection.Input;
                    if (pkey)
                    {
                        p.SourceColumn  = sourceColumn;
                        p.SourceVersion = DataRowVersion.Original;
                        p.Value         = value;
                    }
                    else
                    {
                        p.SourceColumn = null;
                        p.Value        = (ADP.IsNull(value)) ? 1 : 0;
                    }
                    pcount++;
                    valueCount++;

                    if (p is OleDbParameter)
                    {
                        ApplyParameterInfo((OleDbParameter)p, pcount, row);
                    }
                    else if (p is SqlParameter)
                    {
                        ApplyParameterInfo((SqlParameter)p, pcount, row);
                    }
                    else if (p is OdbcParameter)
                    {
                        ApplyParameterInfo((OdbcParameter)p, pcount, row);
                    }
                    if (!pkey)
                    {
                        p.DbType = DbType.Int32;
                    }

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

                if (!pkey)
                {
                    IDataParameter p = GetNextParameter(cmd, valueCount);
                    p.ParameterName = "@p" + pcount.ToString();
                    p.Direction     = ParameterDirection.Input;
                    p.SourceColumn  = sourceColumn;
                    p.SourceVersion = DataRowVersion.Original;
                    p.Value         = value;
                    pcount++;
                    valueCount++;

                    if (p is OleDbParameter)
                    {
                        ApplyParameterInfo((OleDbParameter)p, pcount, row);
                    }
                    else if (p is SqlParameter)
                    {
                        ApplyParameterInfo((SqlParameter)p, pcount, row);
                    }
                    else if (p is OdbcParameter)
                    {
                        ApplyParameterInfo((OdbcParameter)p, pcount, row);
                    }

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

                if (IncrementUpdateWhereCount(row))
                {
                    whereCount++;
                }
            }
            builder.Append(" )");
            cmd.CommandText = builder.ToString();
            RemoveExtraParameters(cmd, valueCount);

#if DEBUG
            if (AdapterSwitches.OleDbSql.TraceInfo)
            {
                ADP.DebugWriteLine(cmd.CommandText);
            }
#endif
            this.updateCommand = cmd;

            if (0 == columnCount)
            {
                throw ADP.DynamicSQLReadOnly(ADP.UpdateCommand);
            }
            if (0 == setCount)   // MDAC 60667
            {
                cmd = null;
            }
            if (0 == whereCount)
            {
                throw ADP.DynamicSQLNoKeyInfo(ADP.UpdateCommand);
            }
            if (null != nullWhereParameter)
            {
                DataColumn column = GetParameterDataColumn(nullWhereSourceColumn, mappings, dataRow);
                throw ADP.WhereClauseUnspecifiedValue(nullWhereParameter, nullWhereSourceColumn, column.ColumnName);
            }
            return(cmd);
        }
예제 #7
0
        private IDbCommand BuildInsertCommand(DataTableMapping mappings, DataRow dataRow)
        {
            if (ADP.IsEmpty(this.quotedBaseTableName))
            {
                return(null);
            }
            IDbCommand cmd = BuildNewCommand(this.insertCommand);

            // count the columns for the ?
            int valueCount = 0;
            int pcount     = 1; // @p1, @p2, ...

            StringBuilder builder = new StringBuilder();

            builder.Append("INSERT INTO ");
            builder.Append(QuotedBaseTableName);

            // search for the columns in that base table, to be the column clause
            int length = this.dbSchemaRows.Length;

            for (int i = 0; i < length; ++i)
            {
                DBSchemaRow row = this.dbSchemaRows[i];
                if (null == row)
                {
                    continue;
                }
                if (0 == row.BaseColumnName.Length)
                {
                    continue;
                }
                if (!row.IsAutoIncrement && !row.IsHidden && !row.IsExpression && !row.IsRowVersion)   // MDAC 68339

                {
                    object value        = null;
                    string sourceColumn = this.sourceColumnNames[i]; // MDAC 60079
                    if ((null != mappings) && (null != dataRow))
                    {
                        value = GetParameterInsertValue(sourceColumn, mappings, dataRow, row.IsReadOnly);
                        if (null == value)
                        {
                            // SQL auto-gen appear to have if (Updatable) then value = DEFAULT
                            // and not check Updateable(IsExpression && IsReadOnly) in the main loop
                            if (row.IsReadOnly || (cmd is SqlCommand))   // MDAC 65473, 68339
                            {
                                continue;
                            }
                        }
                        else if (Convert.IsDBNull(value) && !row.AllowDBNull)   // MDAC 70230
                        {
                            continue;
                        }
                    }
                    if (0 == valueCount)
                    {
                        builder.Append("( ");
                    }
                    else
                    {
                        builder.Append(" , ");
                    }
                    builder.Append(QuotedColumn(row.BaseColumnName));

                    IDataParameter p = GetNextParameter(cmd, valueCount);
                    p.ParameterName = "@p" + pcount.ToString();
                    p.Direction     = ParameterDirection.Input;
                    p.SourceColumn  = sourceColumn;
                    p.SourceVersion = DataRowVersion.Current;
                    p.Value         = value;

                    if (p is OleDbParameter)
                    {
                        ApplyParameterInfo((OleDbParameter)p, pcount, row);
                    }
                    else if (p is SqlParameter)
                    {
                        ApplyParameterInfo((SqlParameter)p, pcount, row);
                    }
                    else if (p is OdbcParameter)
                    {
                        ApplyParameterInfo((OdbcParameter)p, pcount, row);
                    }
                    if (!cmd.Parameters.Contains(p))
                    {
                        cmd.Parameters.Add(p);
                    }
                    valueCount++;
                    pcount++;
                }
            }
            if (0 == valueCount)
            {
                builder.Append(" DEFAULT VALUES");
            }
            else if (this.namedParameters)
            {
                builder.Append(" ) VALUES ( @p1");
                for (int i = 2; i <= valueCount; ++i)
                {
                    builder.Append(" , @p");
                    builder.Append(i.ToString());
                }
                builder.Append(" )");
            }
            else
            {
                builder.Append(" ) VALUES ( ?");
                for (int i = 2; i <= valueCount; ++i)
                {
                    builder.Append(" , ?");
                }
                builder.Append(" )");
            }
            cmd.CommandText = builder.ToString();
            RemoveExtraParameters(cmd, valueCount);
#if DEBUG
            if (AdapterSwitches.OleDbSql.TraceInfo)
            {
                ADP.DebugWriteLine(cmd.CommandText);
            }
#endif

            this.insertCommand = cmd;
            return(cmd);
        }
예제 #8
0
        private void BuildInformation(DataTable schemaTable)
        {
            DBSchemaRow[] rows = DBSchemaRow.GetSortedSchemaRows(schemaTable); // 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();
            }

            if (!ADP.IsEmpty(this.quotePrefix) && (-1 != baseTableName.IndexOf(quotePrefix)))
            {
                throw ADP.DynamicSQLNestedQuote(baseTableName, quotePrefix);
            }
            if (!ADP.IsEmpty(this.quoteSuffix) && (-1 != baseTableName.IndexOf(quoteSuffix)))
            {
                throw ADP.DynamicSQLNestedQuote(baseTableName, quoteSuffix);
            }

            System.Text.StringBuilder quoted = new System.Text.StringBuilder();
            if (null != baseServerName)
            {
                quoted.Append(QuotePrefix);
                quoted.Append(baseServerName);
                quoted.Append(QuoteSuffix);
                quoted.Append(".");
            }
            if (null != baseCatalogName)
            {
                quoted.Append(QuotePrefix);
                quoted.Append(baseCatalogName);
                quoted.Append(QuoteSuffix);
                quoted.Append(".");
            }
            if (null != baseSchemaName)
            {
                quoted.Append(QuotePrefix);
                quoted.Append(baseSchemaName);
                quoted.Append(QuoteSuffix);
                quoted.Append(".");
            }
            quoted.Append(QuotePrefix);
            quoted.Append(baseTableName);
            quoted.Append(QuoteSuffix);
            this.quotedBaseTableName = quoted.ToString();
            this.dbSchemaRows        = rows;
        }
예제 #9
0
 private bool IncrementDeleteWhereCount(DBSchemaRow row)   // MDAC 59255
 {
     return(row.IsKey || row.IsUnique);
 }
예제 #10
0
 private bool IsPKey(DBSchemaRow row)
 {
     return(row.IsKey /* && !row.IsUnique*/);
 }
예제 #11
0
 private bool ExcludeFromUpdateSet(DBSchemaRow row)
 {
     return(row.IsAutoIncrement || row.IsRowVersion || row.IsHidden);
 }
예제 #12
0
        private IDbCommand BuildDeleteCommand(DataTableMapping mappings, DataRow dataRow)
        {
            if (ADP.IsEmpty(this.quotedBaseTableName))
            {
                return(null);
            }
            IDbCommand cmd = BuildNewCommand(this.deleteCommand);

            StringBuilder builder = new StringBuilder();

            builder.Append("DELETE FROM  ");
            builder.Append(QuotedBaseTableName);
            builder.Append(" WHERE ( ");

            int    pcount = 1; // @p1, @p2, ...
            int    valueCount = 0;
            int    whereCount = 0;
            string andclause = "";
            string nullWhereParameter = null, nullWhereSourceColumn = null;

            int length = this.dbSchemaRows.Length;

            for (int i = 0; i < length; ++i)
            {
                DBSchemaRow row = this.dbSchemaRows[i];

                if ((null == row) || (0 == row.BaseColumnName.Length) || !IncludeForDeleteWhereClause(row))
                {
                    continue;
                }
                builder.Append(andclause);
                andclause = CommandBuilder.AndClause;

                object value        = null;
                string sourceColumn = this.sourceColumnNames[i]; // MDAC 60079
                if ((null != mappings) && (null != dataRow))
                {
                    value = GetParameterValue(sourceColumn, mappings, dataRow, DataRowVersion.Original);
                }

                bool   pkey = IsPKey(row);
                string backendColumnName = QuotedColumn(row.BaseColumnName);
                if (pkey)
                {
                    if (Convert.IsDBNull(value))
                    {
                        builder.Append(String.Format(WhereClausepn, backendColumnName));
                    }
                    else if (this.namedParameters)
                    {
                        builder.Append(String.Format(WhereClause1p, backendColumnName, pcount));
                    }
                    else
                    {
                        builder.Append(String.Format(WhereClause2p, backendColumnName));
                    }
                }
                else if (this.namedParameters)
                {
                    builder.Append(String.Format(WhereClause1, backendColumnName, pcount, 1 + pcount));
                }
                else
                {
                    builder.Append(String.Format(WhereClause2, backendColumnName));
                }

                if (!pkey || !Convert.IsDBNull(value))
                {
                    IDataParameter p = GetNextParameter(cmd, valueCount); // first parameter value
                    p.ParameterName = "@p" + pcount.ToString();
                    p.Direction     = ParameterDirection.Input;
                    if (pkey)
                    {
                        p.SourceColumn  = sourceColumn;
                        p.SourceVersion = DataRowVersion.Original;
                        p.Value         = value;
                    }
                    else
                    {
                        p.SourceColumn = null;
                        p.Value        = (ADP.IsNull(value)) ? 1 : 0;
                    }
                    pcount++;
                    valueCount++;

                    if (p is OleDbParameter)
                    {
                        ApplyParameterInfo((OleDbParameter)p, pcount, row);
                    }
                    else if (p is SqlParameter)
                    {
                        ApplyParameterInfo((SqlParameter)p, pcount, row);
                    }
                    else if (p is OdbcParameter)
                    {
                        ApplyParameterInfo((OdbcParameter)p, pcount, row);
                    }
                    if (!pkey)
                    {
                        p.DbType = DbType.Int32;
                    }

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

                if (!pkey)
                {
                    IDataParameter p = GetNextParameter(cmd, valueCount);
                    p.ParameterName = "@p" + pcount.ToString();
                    p.Direction     = ParameterDirection.Input;
                    p.SourceColumn  = sourceColumn;
                    p.SourceVersion = DataRowVersion.Original;
                    p.Value         = value;
                    pcount++;
                    valueCount++;

                    if (p is OleDbParameter)
                    {
                        ApplyParameterInfo((OleDbParameter)p, pcount, row);
                    }
                    else if (p is SqlParameter)
                    {
                        ApplyParameterInfo((SqlParameter)p, pcount, row);
                    }
                    else if (p is OdbcParameter)
                    {
                        ApplyParameterInfo((OdbcParameter)p, pcount, row);
                    }

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

                if (IncrementDeleteWhereCount(row))
                {
                    whereCount++;
                }
            }

            builder.Append(" )");
            cmd.CommandText = builder.ToString();
            RemoveExtraParameters(cmd, valueCount);
#if DEBUG
            if (AdapterSwitches.OleDbSql.TraceInfo)
            {
                ADP.DebugWriteLine(cmd.CommandText);
            }
#endif
            this.deleteCommand = cmd;

            if (0 == whereCount)
            {
                throw ADP.DynamicSQLNoKeyInfo(ADP.DeleteCommand);
            }
            if (null != nullWhereParameter)
            {
                DataColumn column = GetParameterDataColumn(nullWhereSourceColumn, mappings, dataRow);
                throw ADP.WhereClauseUnspecifiedValue(nullWhereParameter, nullWhereSourceColumn, column.ColumnName);
            }

            return(cmd);
        }
예제 #13
0
        private void SetupSchemaWithKeyInfo(MissingMappingAction mappingAction, MissingSchemaAction schemaAction, bool gettingData, DataColumn parentChapterColumn, object chapterValue)
        {
#if DEBUG
            Debug.Assert(null != schemaTable, "null schematable");
            if (AdapterSwitches.DataSchema.TraceVerbose)
            {
                ADP.TraceDataTable("SetupSchema", schemaTable);
            }
#endif
            DBSchemaRow[] schemaRows = DBSchemaRow.GetSortedSchemaRows(schemaTable); // MDAC 60609
            Debug.Assert(null != schemaRows, "SchemaSetup - null DBSchemaRow[]");

            int count = schemaRows.Length;
            if (0 == count)
            {
                this.dataTable = null;
                return;
            }

            bool         addPrimaryKeys = (0 == this.dataTable.PrimaryKey.Length); // MDAC 67033
            DataColumn[] keys           = null;
            int          keyCount       = 0;
            bool         isPrimary      = true; // assume key info (if any) is about a primary key

            int[]  columnIndexMap  = null;
            bool[] chapterIndexMap = null;

            int mappingCount = 0;
            GenerateFieldNames(count);

            DataColumnCollection columnCollection = null;
            for (int sortedIndex = 0; sortedIndex < count; ++sortedIndex)
            {
                DBSchemaRow schemaRow = schemaRows[sortedIndex];

                int unsortedIndex = schemaRow.UnsortedIndex; // MDAC 67050

                DataColumnMapping columnMapping = null;
                Type       fieldType            = schemaRow.DataType;
                DataColumn dataColumn           = null;

                if (!schemaRow.IsHidden)
                {
                    columnMapping = tableMapping.GetColumnMappingBySchemaAction(fieldNames[sortedIndex], mappingAction);
                }

                bool ischapter = false;
                if ((null != columnMapping) && typeof(IDataReader).IsAssignableFrom(fieldType))
                {
                    if (null == chapterIndexMap)
                    {
                        chapterIndexMap = new bool[count];
                    }
                    chapterIndexMap[unsortedIndex] = ischapter = true;

                    fieldType = typeof(Int32);
                }

                if (columnMapping != null)
                {
                    dataColumn = columnMapping.GetDataColumnBySchemaAction(this.dataTable, fieldType, schemaAction);
                }

                if (null == dataColumn)
                {
                    if (null == columnIndexMap)
                    {
                        columnIndexMap = CreateIndexMap(count, unsortedIndex);
                    }
                    columnIndexMap[unsortedIndex] = -1;

                    // if the column is not mapped and it is a key, then don't add any key information
                    if (schemaRow.IsKey)
                    {
#if DEBUG
                        if (AdapterSwitches.DataSchema.TraceVerbose)
                        {
                            Debug.WriteLine("SetupSchema: partial primary key detected");
                        }
#endif
                        addPrimaryKeys = false; // don't add any future keys now
                        keys           = null;  // get rid of any keys we've seen
                    }
                    continue;                   // null means ignore (mapped to nothing)
                }

                if (ischapter)
                {
                    if (null == dataColumn.Table)
                    {
                        dataColumn.AllowDBNull   = false;
                        dataColumn.AutoIncrement = true;
                        dataColumn.ReadOnly      = true;
                    }
                    else if (!dataColumn.AutoIncrement)
                    {
                        throw ADP.FillChapterAutoIncrement();
                    }
                }
                else  // MDAC 67033
                {
                    if (schemaRow.IsAutoIncrement && IsAutoIncrementType(fieldType))
                    {
                        // CONSIDER: use T-SQL "IDENT_INCR('table_or_view')" and "IDENT_SEED('table_or_view')"
                        //           functions to obtain the actual increment and seed values
                        dataColumn.AutoIncrement = true;

                        if (!schemaRow.AllowDBNull)   // MDAC 71060
                        {
                            dataColumn.AllowDBNull = false;
                        }
                    }

                    // setup maxLength, only for string columns since this is all the DataSet supports
                    if (fieldType == typeof(string))
                    {
                        //@devnote:  schemaRow.Size is count of characters for string columns, count of bytes otherwise
                        dataColumn.MaxLength = schemaRow.Size;
                    }

                    if (schemaRow.IsReadOnly)
                    {
                        dataColumn.ReadOnly = true;
                    }
                    if (!schemaRow.AllowDBNull && (!schemaRow.IsReadOnly || schemaRow.IsKey))   // MDAC 71060, 72252
                    {
                        dataColumn.AllowDBNull = false;
                    }

                    if (schemaRow.IsUnique && !schemaRow.IsKey && !fieldType.IsArray)
                    {
                        // note, arrays are not comparable so only mark non-arrays as unique, ie timestamp columns
                        // are unique, but not comparable
                        dataColumn.Unique = true;

                        if (!schemaRow.AllowDBNull)   // MDAC 71060
                        {
                            dataColumn.AllowDBNull = false;
                        }
                    }
                }
                if (null == dataColumn.Table)
                {
                    if (null == columnCollection)
                    {
                        columnCollection = dataTable.Columns;
                    }
                    columnCollection.Add(dataColumn);
                }

                // The server sends us one key per table according to these rules.
                //
                // 1. If the table has a primary key, the server sends us this key.
                // 2. If the table has a primary key and a unique key, it sends us the primary key
                // 3. if the table has no primary key but has a unique key, it sends us the unique key
                //
                // In case 3, we will promote a unique key to a primary key IFF all the columns that compose
                // that key are not nullable since no columns in a primary key can be null.  If one or more
                // of the keys is nullable, then we will add a unique constraint.
                //
                if (addPrimaryKeys && schemaRow.IsKey)   // MDAC 67033
                {
                    if (keys == null)
                    {
                        keys = new DataColumn[count];
                    }
                    keys[keyCount++] = dataColumn;
#if DEBUG
                    if (AdapterSwitches.DataSchema.TraceVerbose)
                    {
                        Debug.WriteLine("SetupSchema: building list of " + ((isPrimary) ? "PrimaryKey" : "UniqueConstraint"));
                    }
#endif
                    // see case 3 above, we do want dataColumn.AllowDBNull not schemaRow.AllowDBNull
                    // otherwise adding PrimaryKey will change AllowDBNull to false
                    if (isPrimary && dataColumn.AllowDBNull)   // MDAC 72241
                    {
#if DEBUG
                        if (AdapterSwitches.DataSchema.TraceVerbose)
                        {
                            Debug.WriteLine("SetupSchema: changing PrimaryKey into UniqueContraint");
                        }
#endif
                        isPrimary = false;
                    }
                }

                if (null != columnIndexMap)
                {
                    columnIndexMap[unsortedIndex] = dataColumn.Ordinal;
                }
                else if (unsortedIndex != dataColumn.Ordinal)
                {
                    columnIndexMap = CreateIndexMap(count, unsortedIndex);
                    columnIndexMap[unsortedIndex] = dataColumn.Ordinal;
                }
                mappingCount++;
            }

            bool       addDataRelation = false;
            DataColumn chapterColumn   = null;
            if (null != chapterValue)   // add the extra column in the child table
            {
                DataColumnMapping columnMapping = tableMapping.GetColumnMappingBySchemaAction(tableMapping.SourceTable, mappingAction);
                if (null != columnMapping)
                {
                    Type fieldType = chapterValue.GetType();
                    chapterColumn = columnMapping.GetDataColumnBySchemaAction(this.dataTable, fieldType, schemaAction);
                    if (null != chapterColumn)
                    {
                        if (null == chapterColumn.Table)
                        {
                            chapterColumn.ReadOnly    = true; // MDAC 71878
                            chapterColumn.AllowDBNull = false;

                            if (null == columnCollection)
                            {
                                columnCollection = dataTable.Columns;
                            }
                            columnCollection.Add(chapterColumn);
                            addDataRelation = (null != parentChapterColumn);
                        }
                        mappingCount++;
                    }
                }
            }

            object[] dataValues = null;
            if (0 < mappingCount)
            {
                if ((null != this.dataSet) && null == this.dataTable.DataSet)
                {
                    this.dataSet.Tables.Add(this.dataTable);
                }
                // setup the key
                if (addPrimaryKeys && (null != keys))   // MDAC 67033
                {
                    if (keyCount < keys.Length)
                    {
                        keys = ResizeColumnArray(keys, keyCount);
                    }

                    // MDAC 66188
                    if (isPrimary)
                    {
#if DEBUG
                        if (AdapterSwitches.DataSchema.TraceVerbose)
                        {
                            Debug.WriteLine("SetupSchema: set_PrimaryKey");
                        }
#endif
                        this.dataTable.PrimaryKey = keys;
                    }
                    else
                    {
                        UniqueConstraint     unique      = new UniqueConstraint("", keys);
                        ConstraintCollection constraints = this.dataTable.Constraints;
                        int constraintCount = constraints.Count;
                        for (int i = 0; i < constraintCount; ++i)
                        {
                            if (unique.Equals(constraints[i]))
                            {
#if DEBUG
                                if (AdapterSwitches.DataSchema.TraceVerbose)
                                {
                                    Debug.WriteLine("SetupSchema: duplicate Contraint detected");
                                }
#endif
                                unique = null;
                                break;
                            }
                        }
                        if (null != unique)
                        {
#if DEBUG
                            if (AdapterSwitches.DataSchema.TraceVerbose)
                            {
                                Debug.WriteLine("SetupSchema: adding new UniqueConstraint");
                            }
#endif
                            constraints.Add(unique);
                        }
                    }
                }
                if (gettingData)
                {
                    if (null == columnCollection)
                    {
                        columnCollection = dataTable.Columns;
                    }
                    _indexMap   = columnIndexMap;
                    _chapterMap = chapterIndexMap;
                    dataValues  = SetupMapping(count, columnCollection, chapterColumn, chapterValue);
                }
#if DEBUG
                else
                {
                    this.mappedMode = -1;
                }
#endif
            }
            else
            {
                this.dataTable = null;
            }
            if (addDataRelation)
            {
                AddRelation(parentChapterColumn, chapterColumn);
            }
            _readerDataValues = dataValues;
        }
예제 #14
0
 internal void AddRow(DBSchemaRow dataRow)
 {
     dataTable.Rows.Add(dataRow.DataRow);
     dataRow.DataRow.AcceptChanges();
 }