Exemplo n.º 1
0
            public DocumentMappingExpression <T> UniqueIndex(UniqueIndexType indexType, string indexName,
                                                             TenancyScope tenancyScope = TenancyScope.Global, params Expression <Func <T, object> >[] expressions)
            {
                _builder.Alter = m => m.UniqueIndex(indexType, indexName, tenancyScope, expressions);

                return(this);
            }
Exemplo n.º 2
0
        public IEnumerable <ObjectState> GetDesiredState(SchemaConnection connection, IOutput output)
        {
            var schemaDriver = connection.SchemaDriver;

            var stateTable     = TableType.Create("dbo.nrdo_object");
            var stateTypeField = FieldType.Create(stateTable.Identifier, "type", 0, "nvarchar(100)", false);
            var stateNameField = FieldType.Create(stateTable.Identifier, "name", 1, "nvarchar(500)", false);
            var statePk        = UniqueIndexType.CreatePrimaryKey(stateTable.Identifier, "nrdo_object_pk",
                                                                  new[] { stateTypeField.Identifier, stateNameField.Identifier },
                                                                  schemaDriver.DefaultPrimaryKeyCustomState);

            var subTable           = TableType.Create("dbo.nrdo_object_sub");
            var subParentTypeField = FieldType.Create(subTable.Identifier, "parent_type", 0, "nvarchar(100)", false);
            var subParentNameField = FieldType.Create(subTable.Identifier, "parent_name", 1, "nvarchar(500)", false);
            var subTypeField       = FieldType.Create(subTable.Identifier, "type", 2, "nvarchar(100)", false);
            var subNameField       = FieldType.Create(subTable.Identifier, "name", 3, "nvarchar(500)", false);
            var subPk = UniqueIndexType.CreatePrimaryKey(subTable.Identifier, "nrdo_object_sub_pk",
                                                         new[] { subParentTypeField.Identifier, subParentNameField.Identifier, subTypeField.Identifier, subNameField.Identifier },
                                                         schemaDriver.DefaultPrimaryKeyCustomState);
            var subFk = FkeyType.Create(subTable.Identifier, stateTable.Identifier, "nrdo_object_sub_parent_fk", true, new[] {
                new FieldPair(subParentTypeField.Name, stateTypeField.Name),
                new FieldPair(subParentNameField.Name, stateNameField.Name),
            });

            return(new ObjectState[] {
                stateTable, stateTypeField, stateNameField, statePk, subTable, subParentTypeField, subParentNameField, subTypeField, subNameField, subPk, subFk
            });
        }
Exemplo n.º 3
0
            public DocumentMappingExpression <T> UniqueIndex(UniqueIndexType indexType,
                                                             params Expression <Func <T, object> >[] expressions)
            {
                _builder.Alter = m => m.UniqueIndex(indexType, null, expressions);

                return(this);
            }
Exemplo n.º 4
0
        public static bool FkeyHasChanged(SchemaChanges changes, SubObjectState <FkeyType, FkeyType.State> current)
        {
            if (current == null)
            {
                return(true);
            }

            var desired = changes.Desired.Get(current);

            // The foreign key doesn't exist in the desired schema at all
            if (desired == null)
            {
                return(true);
            }

            // The destination table has changed
            if (desired.State.ToTable != current.State.ToTable)
            {
                return(true);
            }

            // Either the from or to table might need to be dropped entirely to reorder fields
            if (FieldType.IsFieldReorderPossiblyNeeded(changes, current.ParentIdentifier) ||
                FieldType.IsFieldReorderPossiblyNeeded(changes, current.State.ToTable))
            {
                return(true);
            }

            // It's changed from cascading to not or vice versa
            if (desired.State.IsCascadeDelete != current.State.IsCascadeDelete)
            {
                return(true);
            }

            // The sequence of field name pairs don't match
            if (!Enumerable.SequenceEqual(desired.State.Joins, current.State.Joins, FieldPair.GetComparer(changes.DbDriver)))
            {
                return(true);
            }

            // Any of the fields in either table are changing
            if (current.State.Joins.Any(field =>
                                        FieldType.FieldHasChanged(changes, current.ParentIdentifier, FieldType.Identifier(field.FromFieldName)) ||
                                        FieldType.FieldHasChanged(changes, current.State.ToTable, FieldType.Identifier(field.ToFieldName))))
            {
                return(true);
            }

            // The unique index on the destination table that corresponds to the destination fields is changing
            var ukey = UniqueIndexType.ChildrenFrom(changes.Current, current.State.ToTable)
                       .SingleOrDefault(key => new HashSet <Identifier>(key.State.IndexState.Fields).SetEquals(from field in current.State.Joins
                                                                                                               select FieldType.Identifier(field.ToFieldName)));

            if (ukey != null && UniqueIndexType.IndexHasChanged(changes, ukey))
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 5
0
        public void UniqueIndex(UniqueIndexType indexType, string indexName,
                                TenancyScope tenancyScope = TenancyScope.Global, params Expression <Func <T, object> >[] expressions)
        {
            var members = expressions
                          .Select(e =>
            {
                var visitor = new FindMembers();
                visitor.Visit(e);
                return(visitor.Members.ToArray());
            })
                          .ToArray();

            if (members.Length == 0)
            {
                throw new InvalidOperationException(
                          $"Unique index on {typeof(T)} requires at least one property/field");
            }

            AddUniqueIndex(
                members,
                indexType,
                indexName,
                IndexMethod.btree,
                tenancyScope);
        }
Exemplo n.º 6
0
 public void UniqueIndex(UniqueIndexType indexType, string indexName,
                         TenancyScope tenancyScope = TenancyScope.Global, params Expression <Func <T, object> >[] expressions)
 {
     AddUniqueIndex(
         expressions
         .Select(FindMembers.Determine)
         .ToArray(),
         indexType,
         indexName,
         IndexMethod.btree,
         tenancyScope);
 }
Exemplo n.º 7
0
        internal static bool FulltextIndexHasChanged(SchemaChanges changes, SubObjectState <FulltextIndexType, State> current)
        {
            if (current == null)
            {
                return(true);
            }

            var desired = changes.Desired.Get(current);

            // The fulltext index doesn't exist in the desired schema at all
            if (desired == null)
            {
                return(true);
            }

            // The key index name has changed
            if (desired.State.KeyName != current.State.KeyName)
            {
                return(true);
            }

            // The set of affected columns has changed (in some way other than just the ordering)
            if (!ImmutableHashSet.CreateRange(changes.DbDriver.DbStringComparer, desired.State.Columns).SetEquals(current.State.Columns))
            {
                return(true);
            }

            var table = TableType.Identifier(desired.Name);

            // Any of the columns in the fulltext index have changed
            if (desired.State.Columns.Any(col => FieldType.FieldHasChanged(changes, table, FieldType.Identifier(col))))
            {
                return(true);
            }

            // The key index is to be dropped
            // This includes the case where the table itself may be dropped for reordering
            if (UniqueIndexType.IndexHasChanged(changes, UniqueIndexType.GetFrom(changes.Current, table, UniqueIndexType.Identifier(current.State.KeyName))))
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 8
0
 public void UniqueIndex(UniqueIndexType indexType, string indexName,
                         params Expression <Func <T, object> >[] expressions)
 {
     UniqueIndex(indexType, indexName, TenancyScope.Global, expressions);
 }
Exemplo n.º 9
0
            /// <summary>
            /// Creates a unique index on this data member within the JSON data storage
            /// </summary>
            /// <param name="indexType">Type of the index</param>
            /// <param name="indexName">Name of the index</param>
            /// <param name="expressions"></param>
            /// <returns></returns>
            public DocumentMappingExpression <T> UniqueIndex(UniqueIndexType indexType, string indexName, params Expression <Func <T, object> >[] expressions)
            {
                alter = m => m.UniqueIndex(indexType, indexName, expressions);

                return(this);
            }
Exemplo n.º 10
0
        public IEnumerable <ObjectState> GetDesiredState(SchemaConnection connection, IOutput output)
        {
            var schemaDriver  = connection.SchemaDriver;
            var sqlTranslator = new SqlTranslator(schemaDriver, null);

            HashSet <string> catalogs = new HashSet <string>(schemaDriver.DbDriver.DbStringComparer);

            foreach (var nrdoTable in codeBase.AllTables)
            {
                if (nrdoTable.ExistingName != null)
                {
                    if (nrdoTable.BeforeStatements.Any())
                    {
                        throw new ApplicationException("Table " + nrdoTable.Name + " is 'existing' but has before statements, which is no longer supported");
                    }
                    continue;
                }

                output.Verbose("Loading table " + nrdoTable.DatabaseName + " from " + nrdoTable.Type.Name);
                var table = TableType.Create(schemaName + "." + nrdoTable.DatabaseName);
                yield return(table);

                if (preserveColumnOrder)
                {
                    yield return(FieldOrderSensitivityType.Create(table.Identifier));
                }

                string sequencedPkeyFieldName = null;
                string sequenceName           = null;
                if (nrdoTable.IsPkeySequenced)
                {
                    sequencedPkeyFieldName = nrdoTable.PkeyGet.Fields.Single().Name;
                    var sequenceNameBase = getNameHashString(nrdoTable.Name) + "_" + sequencedPkeyFieldName;

                    if (schemaDriver.IsSequenceUsed)
                    {
                        sequenceName = "sq_" + sequenceNameBase;
                        yield return(SequenceType.Create(schemaName + "." + sequenceName));
                    }

                    if (schemaDriver.IsTriggerUsedForSequence)
                    {
                        var triggerName = "sqt_" + sequenceNameBase;
                        yield return(TriggerType.Create(table.Identifier, triggerName, schemaDriver.GetSequencedFieldTriggerTiming(), TriggerEvents.Insert,
                                                        schemaDriver.GetSequencedFieldTriggerBody(table.Name, sequencedPkeyFieldName, sequenceName)));
                    }
                }

                var fieldIndex = 0;
                foreach (var nrdoField in nrdoTable.Fields)
                {
                    if (nrdoField.Name == sequencedPkeyFieldName)
                    {
                        yield return(FieldType.CreateSequencedPkey(table.Identifier, nrdoField.Name, fieldIndex++, nrdoField.DbType, nrdoField.IsNullable, sequenceName));
                    }
                    else
                    {
                        yield return(FieldType.Create(table.Identifier, nrdoField.Name, fieldIndex++, nrdoField.DbType, nrdoField.IsNullable));
                    }
                }

                foreach (var nrdoIndex in nrdoTable.Indexes)
                {
                    if (nrdoIndex.IsPrimary)
                    {
                        yield return(UniqueIndexType.CreatePrimaryKey(table.Identifier, nrdoIndex.Name,
                                                                      from field in nrdoIndex.Fields select FieldType.Identifier(field), schemaDriver.DefaultPrimaryKeyCustomState));
                    }
                    else if (nrdoIndex.IsUnique)
                    {
                        yield return(UniqueIndexType.CreateUnique(table.Identifier, nrdoIndex.Name,
                                                                  from field in nrdoIndex.Fields select FieldType.Identifier(field), schemaDriver.DefaultUniqueConstraintCustomState));
                    }
                    else
                    {
                        yield return(NonUniqueIndexType.Create(table.Identifier, nrdoIndex.Name,
                                                               from field in nrdoIndex.Fields select FieldType.Identifier(field), schemaDriver.DefaultIndexCustomState));
                    }
                }

                if (nrdoTable.FulltextFields.Any() && connection.SchemaDriver.IsFulltextSupported(connection))
                {
                    var catalog = nrdoTable.FulltextCatalog ?? "NrdoFulltext";
                    if (!catalogs.Contains(catalog))
                    {
                        yield return(FulltextCatalogType.Create(catalog));

                        catalogs.Add(catalog);
                    }

                    var pkey = nrdoTable.Indexes.Where(index => index.IsPrimary).Single();
                    yield return(FulltextIndexType.Create(table.Identifier, FulltextCatalogType.Identifier(catalog), pkey.Name, nrdoTable.FulltextFields));
                }

                foreach (var nrdoFkey in nrdoTable.References)
                {
                    if (nrdoFkey.IsFkey)
                    {
                        yield return(FkeyType.Create(table.Identifier, TableType.Identifier(schemaName + "." + nrdoFkey.TargetTable.DatabaseName),
                                                     nrdoFkey.FkeyName, nrdoFkey.IsCascadingFkey,
                                                     from fjoin in nrdoFkey.Joins select new FieldPair(fjoin.From.Name, fjoin.To.Name)));
                    }
                }

                var beforeIndex = 0;
                foreach (var nrdoBefore in nrdoTable.BeforeStatements)
                {
                    yield return(BeforeStatementType.Create(table.Identifier, "0" + nrdoTable.Name, beforeIndex++, nrdoBefore.Name, nrdoBefore.Step,
                                                            nrdoBefore.Initial, nrdoBefore.Upgrade, sqlTranslator.Translate(nrdoBefore.Statement)));
                }

                foreach (var oldName in nrdoTable.RenamedFrom)
                {
                    var oldDbName = schemaName + "." + oldName.Replace(':', '_');
                    yield return(TableRenameType.Create(oldDbName, table.Name));
                }
            }

            foreach (var nrdoQuery in codeBase.AllQueries)
            {
                output.Verbose("Loading query " + nrdoQuery.DatabaseName + " from " + nrdoQuery.Type.Name);

                var queryName = schemaName + "." + nrdoQuery.DatabaseName;

                var parameters = from param in nrdoQuery.Params select new ProcParam(param.Name, param.DbType);

                if (nrdoQuery.IsStoredProc)
                {
                    yield return(QueryType.CreateProc(queryName, parameters, sqlTranslator.Translate(nrdoQuery.Sql)));

                    if (nrdoQuery.IsPreUpgradeHook)
                    {
                        yield return(PreUpgradeHookType.Create(queryName));
                    }
                }
                else if (nrdoQuery.IsStoredFunction)
                {
                    var returnType = nrdoQuery.Results.Single().DbType;
                    yield return(QueryType.CreateFunction(queryName, parameters, returnType, sqlTranslator.Translate(nrdoQuery.Sql)));
                }
                else
                {
                    yield return(QueryType.CreateUnstored(queryName));
                }

                var beforeIndex = 0;
                foreach (var nrdoBefore in nrdoQuery.BeforeStatements)
                {
                    yield return(BeforeStatementType.Create(QueryType.Identifier(queryName), "1" + nrdoQuery.Name, beforeIndex++, nrdoBefore.Name, nrdoBefore.Step,
                                                            nrdoBefore.Initial, nrdoBefore.Upgrade, sqlTranslator.Translate(nrdoBefore.Statement)));
                }
            }
        }