Exemple #1
0
        public static void AddConstraint(this IQuery query, ObjectName tableName, ConstraintInfo constraintInfo)
        {
            if (constraintInfo.ConstraintType == ConstraintType.PrimaryKey)
            {
                var columnNames = constraintInfo.ColumnNames;
                if (columnNames.Length > 1)
                {
                    throw new ArgumentException();
                }

                query.AddPrimaryKey(tableName, columnNames[0], constraintInfo.ConstraintName);
            }
            else if (constraintInfo.ConstraintType == ConstraintType.Unique)
            {
                query.AddUniqueKey(tableName, constraintInfo.ColumnNames, constraintInfo.ConstraintName);
            }
            else if (constraintInfo.ConstraintType == ConstraintType.Check)
            {
                query.AddCheck(tableName, constraintInfo.CheckExpression, constraintInfo.ConstraintName);
            }
            else if (constraintInfo.ConstraintType == ConstraintType.ForeignKey)
            {
                query.AddForeignKey(tableName, constraintInfo.ColumnNames, constraintInfo.ForeignTable,
                                    constraintInfo.ForeignColumnNames, constraintInfo.OnDelete, constraintInfo.OnUpdate, constraintInfo.ConstraintName);
            }
        }
Exemple #2
0
        public static ConstraintInfo ForeignKey(string constraintName, ObjectName tableName, string[] columnNames,
                                                ObjectName refTable, string[] refColumns)
        {
            if (tableName == null)
            {
                throw new ArgumentNullException("tableName");
            }
            if (refTable == null)
            {
                throw new ArgumentNullException("refTable");
            }
            if (columnNames == null || columnNames.Length == 0)
            {
                throw new ArgumentException("At least one column is required", "columnNames");
            }
            if (refColumns == null || refColumns.Length == 0)
            {
                throw new ArgumentException("At least one referenced column is required.", "refColumns");
            }

            if (columnNames.Length != refColumns.Length)
            {
                throw new ArgumentException("The number of columns in the constraint must match the number of columns referenced.");
            }

            var constraint = new ConstraintInfo(constraintName, ConstraintType.ForeignKey, tableName, columnNames);

            constraint.ForeignTable       = refTable;
            constraint.ForeignColumnNames = refColumns;
            return(constraint);
        }
Exemple #3
0
        public StatementResult(ICursor cursor, ConstraintInfo[] constraints)
        {
            if (cursor == null)
                throw new ArgumentNullException("cursor");

            Cursor = cursor;
            Constraints = constraints;
            Type = StatementResultType.CursorRef;
        }
Exemple #4
0
        public StatementResult(ITable result, ConstraintInfo[] constraints)
        {
            if (result == null)
                throw new ArgumentNullException("result");

            Result = result;
            Constraints = constraints;
            Type = StatementResultType.Result;
        }
        public static void AddConstraint(this IQuery query, ObjectName tableName, ConstraintInfo constraintInfo)
        {
            if (constraintInfo.ConstraintType == ConstraintType.PrimaryKey) {
                var columnNames = constraintInfo.ColumnNames;
                if (columnNames.Length > 1)
                    throw new ArgumentException();

                query.AddPrimaryKey(tableName, columnNames[0], constraintInfo.ConstraintName);
            } else if (constraintInfo.ConstraintType == ConstraintType.Unique) {
                query.AddUniqueKey(tableName, constraintInfo.ColumnNames, constraintInfo.ConstraintName);
            } else if (constraintInfo.ConstraintType == ConstraintType.Check) {
                query.AddCheck(tableName, constraintInfo.CheckExpression, constraintInfo.ConstraintName);
            } else if (constraintInfo.ConstraintType == ConstraintType.ForeignKey) {
                query.AddForeignKey(tableName, constraintInfo.ColumnNames, constraintInfo.ForeignTable,
                    constraintInfo.ForeignColumnNames, constraintInfo.OnDelete, constraintInfo.OnUpdate, constraintInfo.ConstraintName);
            }
        }
        protected override void ExecuteStatement(ExecutionContext context)
        {
            //if (!context.User.CanAlterTable(TableName))
            //	throw new InvalidAccessException(context.Request.UserName(), TableName);

            var table = context.Request.Access().GetTable(TableName);
            if (table == null)
                throw new ObjectNotFoundException(TableName);

            var tableInfo = table.TableInfo;
            var newTableInfo = new TableInfo(tableInfo.TableName);

            var checker = ColumnChecker.Default(context.Request, TableName);

            bool tableAltered = false;
            bool markDropped = false;

            for (int n = 0; n < tableInfo.ColumnCount; ++n) {
                var column = tableInfo[n];

                string columnName = column.ColumnName;
                var columnType = column.ColumnType;
                var defaultExpression = column.DefaultExpression;

                if (Action.ActionType == AlterTableActionType.SetDefault &&
                    CheckColumnNamesMatch(context.Request, ((SetDefaultAction)Action).ColumnName, columnName)) {
                    var exp = ((SetDefaultAction)Action).DefaultExpression;
                    exp = checker.CheckExpression(exp);
                    defaultExpression = exp;
                    tableAltered = true;
                } else if (Action.ActionType == AlterTableActionType.DropDefault &&
                           CheckColumnNamesMatch(context.Request, ((DropDefaultAction)Action).ColumnName, columnName)) {
                    defaultExpression = null;
                    tableAltered = true;
                } else if (Action.ActionType == AlterTableActionType.DropColumn &&
                           CheckColumnNamesMatch(context.Request, ((DropColumnAction)Action).ColumnName, columnName)) {
                    // Check there are no referential links to this column
                    var refs = context.Request.Access().QueryTableImportedForeignKeys(TableName);
                    foreach (var reference in refs) {
                        CheckColumnConstraint(columnName, reference.ForeignColumnNames, reference.ForeignTable, reference.ConstraintName);
                    }

                    // Or from it
                    refs = context.Request.Access().QueryTableForeignKeys(TableName);
                    foreach (var reference in refs) {
                        CheckColumnConstraint(columnName, reference.ColumnNames, reference.TableName, reference.ConstraintName);
                    }

                    // Or that it's part of a primary key
                    var primaryKey = context.Request.Access().QueryTablePrimaryKey(TableName);
                    if (primaryKey != null)
                        CheckColumnConstraint(columnName, primaryKey.ColumnNames, TableName, primaryKey.ConstraintName);

                    // Or that it's part of a unique set
                    var uniques = context.Request.Access().QueryTableUniqueKeys(TableName);
                    foreach (var unique in uniques) {
                        CheckColumnConstraint(columnName, unique.ColumnNames, TableName, unique.ConstraintName);
                    }

                    markDropped = true;
                    tableAltered = true;
                }

                var newColumn = new ColumnInfo(columnName, columnType);
                if (defaultExpression != null)
                    newColumn.DefaultExpression = defaultExpression;

                newColumn.IndexType = column.IndexType;
                newColumn.IsNotNull = column.IsNotNull;

                // If not dropped then add to the new table definition.
                if (!markDropped) {
                    newTableInfo.AddColumn(newColumn);
                }
            }

            if (Action.ActionType == AlterTableActionType.AddColumn) {
                var col = ((AddColumnAction)Action).Column;

                checker.CheckExpression(col.DefaultExpression);
                var columnName = col.ColumnName;
                var columnType = col.ColumnType;

                // If column name starts with [table_name]. then strip it off
                columnName = checker.StripTableName(TableName.Name, columnName);
                if (tableInfo.IndexOfColumn(col.ColumnName) != -1)
                    throw new InvalidOperationException("The column '" + col.ColumnName + "' is already in the table '" + tableInfo.TableName + "'.");

                var newColumn = new ColumnInfo(columnName, columnType) {
                    IsNotNull = col.IsNotNull,
                    DefaultExpression = col.DefaultExpression
                };

                newTableInfo.AddColumn(newColumn);
                tableAltered = true;
            }

            if (Action.ActionType == AlterTableActionType.DropConstraint) {
                string constraintName = ((DropConstraintAction)Action).ConstraintName;
                int dropCount = context.Request.Access().DropTableConstraint(TableName, constraintName);
                if (dropCount == 0)
                    throw new InvalidOperationException("Named constraint to drop on table " + TableName + " was not found: " + constraintName);
            } else if (Action.ActionType == AlterTableActionType.DropPrimaryKey) {
                if (!context.Request.Access().DropTablePrimaryKey(TableName, null))
                    throw new InvalidOperationException("No primary key to delete on table " + TableName);
            }

            if (Action.ActionType == AlterTableActionType.AddConstraint) {
                var constraint = ((AddConstraintAction)Action).Constraint;
                bool foreignConstraint = (constraint.ConstraintType == ConstraintType.ForeignKey);

                ObjectName refTname = null;
                if (foreignConstraint) {
                    refTname = context.Request.Access().ResolveTableName(constraint.ReferenceTable);
                }

                var columnNames = checker.StripColumnList(TableName.FullName, constraint.Columns);
                columnNames = checker.StripColumnList(constraint.ReferenceTable, columnNames);
                var expression = checker.CheckExpression(constraint.CheckExpression);
                columnNames = checker.CheckColumns(columnNames);

                IEnumerable<string> refCols = null;
                if (foreignConstraint && constraint.ReferenceColumns != null) {
                    var referencedChecker = ColumnChecker.Default(context.Request, refTname);
                    refCols = referencedChecker.CheckColumns(constraint.ReferenceColumns);
                }

                var newConstraint = new ConstraintInfo(constraint.ConstraintName, constraint.ConstraintType, TableName, columnNames.ToArray());
                if (foreignConstraint) {
                    if (refCols == null)
                        throw new InvalidOperationException("Could not create a Foreign Key constraint with no reference columns");

                    newConstraint.ForeignTable = refTname;
                    newConstraint.ForeignColumnNames = refCols.ToArray();
                    newConstraint.OnDelete = constraint.OnDelete;
                    newConstraint.OnUpdate = constraint.OnUpdate;
                }

                if (constraint.ConstraintType == ConstraintType.Check)
                    newConstraint.CheckExpression = expression;

                context.Request.Access().AddConstraint(TableName, newConstraint);
            }

            // Alter the existing table to the new format...
            if (tableAltered) {
                if (newTableInfo.ColumnCount == 0)
                    throw new InvalidOperationException("Can not ALTER table to have 0 columns.");

                context.DirectAccess.AlterObject(newTableInfo);
            } else {
                // If the table wasn't physically altered, check the constraints.
                // Calling this method will also make the transaction check all
                // deferred constraints during the next commit.
                context.Request.Access().CheckConstraintViolations(TableName);
            }
        }
        public static ConstraintInfo ForeignKey(string constraintName, ObjectName tableName, string[] columnNames,
			ObjectName refTable, string[] refColumns)
        {
            if (tableName == null)
                throw new ArgumentNullException("tableName");
            if (refTable == null)
                throw new ArgumentNullException("refTable");
            if (columnNames == null || columnNames.Length == 0)
                throw new ArgumentException("At least one column is required", "columnNames");
            if (refColumns == null || refColumns.Length == 0)
                throw new ArgumentException("At least one referenced column is required.", "refColumns");

            if (columnNames.Length != refColumns.Length)
                throw new ArgumentException("The number of columns in the constraint must match the number of columns referenced.");

            var constraint = new ConstraintInfo(constraintName, ConstraintType.ForeignKey, tableName, columnNames);
            constraint.ForeignTable = refTable;
            constraint.ForeignColumnNames = refColumns;
            return constraint;
        }