private static string FormatMessage(ObjectName tableName, string constraintName, string[] columnNames, ConstraintDeferrability deferrability)
 {
     return String.Format("{0} UNIQUE KEY violation for constraint '{1}({2})' on table '{3}'.",
     deferrability.AsDebugString(), constraintName, String.Join(", ", columnNames), tableName);
 }
 private static string FormatMessage(ObjectName tableName, string constraintName, string[] columnNames, ObjectName refTableName, string[] refColumnNames, ConstraintDeferrability deferrability)
 {
     return String.Format("{0} FOREIGN KEY violation for constraint '{1}({2})' referencing '{3}({4})'",
         deferrability.AsDebugString(), constraintName, String.Join(", ", columnNames), refTableName,
         String.Join(", ", refColumnNames));
 }
        public static void CheckRemoveConstraintViolations(this ITransaction transaction, ITable table, int[] rowIndices, ConstraintDeferrability deferred)
        {
            // Quick exit case
            if (rowIndices == null || rowIndices.Length == 0)
                return;

            var tableInfo = table.TableInfo;
            var tableName = tableInfo.TableName;

            // Check any imported foreign key constraints.
            // This ensures that a referential reference can not be removed making
            // it invalid.
            var foreignConstraints = transaction.QueryTableImportedForeignKeys(tableName);
            foreach (var reference in foreignConstraints) {
                if (deferred == ConstraintDeferrability.InitiallyDeferred ||
                    reference.Deferred == ConstraintDeferrability.InitiallyImmediate) {
                    // For each row removed from this column
                    foreach (int rowIndex in rowIndices) {
                        // Make sure the referenced record exists

                        // Return the count of records where the given row of
                        //   ref_table_name(columns, ...) IN
                        //                    table_name(ref_columns, ...)
                        int rowCount = RowCountOfReferenceTable(transaction,
                                                   rowIndex,
                                                   reference.ForeignTable, reference.ForeignColumnNames,
                                                   reference.TableName, reference.ColumnNames,
                                                   true);
                        // There must be 0 references otherwise the delete isn't allowed to
                        // happen.
                        if (rowCount > 0) {
                            throw new ConstraintViolationException(SqlModelErrorCodes.ForeignKeyViolation,
                              deferred.AsDebugString() + " foreign key constraint violation " +
                              "on delete (" +
                              reference.ConstraintName + ") Columns = " +
                              reference.TableName + "( " +
                              String.Join(", ", reference.ColumnNames) + " ) -> " +
                              reference.ForeignTable + "( " +
                              String.Join(", ", reference.ForeignColumnNames) + " )");
                        }
                    }
                }
            }
        }
        public static void CheckAddConstraintViolations(this ITransaction transaction, ITable table, int[] rowIndices, ConstraintDeferrability deferred)
        {
            string curSchema = table.TableInfo.TableName.Parent.Name;
            IQueryContext queryContext = new SystemQueryContext(transaction, curSchema);

            // Quick exit case
            if (rowIndices == null || rowIndices.Length == 0)
                return;

            var tableInfo = table.TableInfo;
            var tableName = tableInfo.TableName;

            // ---- Constraint checking ----

            // Check any primary key constraint.
            var primaryKey = transaction.QueryTablePrimaryKey(tableName);
            if (primaryKey != null &&
                (deferred == ConstraintDeferrability.InitiallyDeferred ||
                 primaryKey.Deferred == ConstraintDeferrability.InitiallyImmediate)) {

                // For each row added to this column
                foreach (int rowIndex in rowIndices) {
                    if (!IsUniqueColumns(table, rowIndex, primaryKey.ColumnNames, false)) {
                        throw new ConstraintViolationException(
                          SqlModelErrorCodes.PrimaryKeyViolation,
                          deferred.AsDebugString() + " primary Key constraint violation (" +
                          primaryKey.ConstraintName + ") Columns = ( " +
                          String.Join(", ", primaryKey.ColumnNames) +
                          " ) Table = ( " + tableName + " )");
                    }
                } // For each row being added
            }

            // Check any unique constraints.
            var uniqueConstraints = transaction.QueryTableUniqueKeys(tableName);
            foreach (var unique in uniqueConstraints) {
                if (deferred == ConstraintDeferrability.InitiallyDeferred ||
                    unique.Deferred == ConstraintDeferrability.InitiallyImmediate) {

                    // For each row added to this column
                    foreach (int rowIndex in rowIndices) {
                        if (!IsUniqueColumns(table, rowIndex, unique.ColumnNames, true)) {
                            throw new ConstraintViolationException(
                              SqlModelErrorCodes.UniqueViolation,
                              deferred.AsDebugString() + " unique constraint violation (" +
                              unique.ConstraintName + ") Columns = ( " +
                              String.Join(", ", unique.ColumnNames) + " ) Table = ( " +
                              tableName + " )");
                        }
                    } // For each row being added
                }
            }

            // Check any foreign key constraints.
            // This ensures all foreign references in the table are referenced
            // to valid records.
            var foreignConstraints = transaction.QueryTableForeignKeys(tableName);

            foreach (var reference in foreignConstraints) {
                if (deferred == ConstraintDeferrability.InitiallyDeferred ||
                    reference.Deferred == ConstraintDeferrability.InitiallyImmediate) {
                    // For each row added to this column
                    foreach (int rowIndex in rowIndices) {
                        // Make sure the referenced record exists

                        // Return the count of records where the given row of
                        //   table_name(columns, ...) IN
                        //                    ref_table_name(ref_columns, ...)
                        int rowCount = RowCountOfReferenceTable(transaction,
                                                   rowIndex,
                                                   reference.TableName, reference.ColumnNames,
                                                   reference.ForeignTable, reference.ForeignColumnNames,
                                                   false);
                        if (rowCount == -1) {
                            // foreign key is NULL
                        }

                        if (rowCount == 0) {
                            throw new ConstraintViolationException(
                              SqlModelErrorCodes.ForeignKeyViolation,
                              deferred.AsDebugString() + " foreign key constraint violation (" +
                              reference.ConstraintName + ") Columns = " +
                              reference.TableName + "( " +
                              String.Join(", ", reference.ColumnNames) + " ) -> " +
                              reference.ForeignTable + "( " +
                              String.Join(", ", reference.ForeignColumnNames) + " )");
                        }
                    } // For each row being added.
                }
            }

            // Any general checks of the inserted data
            var checkConstraints = transaction.QueryTableCheckExpressions(tableName);

            // For each check constraint, check that it evaluates to true.
            for (int i = 0; i < checkConstraints.Length; ++i) {
                var check = checkConstraints[i];
                if (deferred == ConstraintDeferrability.InitiallyDeferred ||
                    check.Deferred == ConstraintDeferrability.InitiallyImmediate) {

                    // TODO: var exp = tableInfo.ResolveColumns(transaction.IgnoreIdentifierCase(), check.CheckExpression);
                    var exp = tableInfo.ResolveColumns(true, check.CheckExpression);

                    // For each row being added to this column
                    for (int rn = 0; rn < rowIndices.Length; ++rn) {
                        var resolver = new TableRowVariableResolver(table, rowIndices[rn]);
                        var evalExp = exp.Evaluate(queryContext, resolver, null);
                        var ob = ((SqlConstantExpression) evalExp).Value;

                        var b = ob.AsBoolean();

                        if (!b.IsNull) {
                            if (b) {
                                // Evaluated to false so don't allow this row to be added.
                                throw new ConstraintViolationException(
                                   SqlModelErrorCodes.CheckViolation,
                                   deferred.AsDebugString() + " check constraint violation (" +
                                   check.ConstraintName + ") - '" + exp +
                                   "' evaluated to false for inserted/updated row.");
                            }
                        } else {
                            // NOTE: This error will pass the row by default
                            // TODO: emit a warning
                        }
                    }
                }
            }
        }
示例#5
0
 private static string FormatMessage(ObjectName tableName, string constraintName, string[] columnNames, ConstraintDeferrability deferrability)
 {
     return(String.Format("{0} UNIQUE KEY violation for constraint '{1}({2})' on table '{3}'.",
                          deferrability.AsDebugString(), constraintName, String.Join(", ", columnNames), tableName));
 }
 private static string FormatMessage(ObjectName tableName, string constraintName, string[] columnNames, ObjectName refTableName, string[] refColumnNames, ConstraintDeferrability deferrability)
 {
     return(String.Format("{0} FOREIGN KEY violation for constraint '{1}({2})' referencing '{3}({4})'",
                          deferrability.AsDebugString(), constraintName, String.Join(", ", columnNames), refTableName,
                          String.Join(", ", refColumnNames)));
 }