예제 #1
0
        public void no_current_version_argument_if_not_configured_on_the_mapping()
        {
            var mapping = DocumentMapping.For<Issue>();
            mapping.UseOptimisticConcurrency = false;

            var func = new UpsertFunction(mapping);

            func.OrderedArguments().OfType<CurrentVersionArgument>().Any()
                .ShouldBeFalse();
        }
예제 #2
0
        public void add_the_optimistic_version_arg_if_mapping_has_that()
        {
            var mapping = DocumentMapping.For<Issue>();
            mapping.UseOptimisticConcurrency = true;

            var func = new UpsertFunction(mapping);

            func.OrderedArguments().OfType<CurrentVersionArgument>().Any()
                .ShouldBeTrue();
        }
예제 #3
0
        public SchemaDiff(SchemaObjects existing, DocumentMapping mapping, DdlRules rules)
        {
            if (existing.HasNone())
            {
                AllMissing = true;
            }
            else
            {
                var expectedTable = mapping.SchemaObjects.As<DocumentSchemaObjects>().StorageTable();
                TableDiff = new TableDiff(expectedTable, existing.Table);

                // TODO -- drop obsolete indices?

                mapping.Indexes.Each(index =>
                {
                    if (existing.ActualIndices.ContainsKey(index.IndexName))
                    {
                        var actualIndex = existing.ActualIndices[index.IndexName];
                        if (!index.Matches(actualIndex))
                        {
                            IndexChanges.Add($"drop index {expectedTable.Table.Schema}.{index.IndexName};{Environment.NewLine}{index.ToDDL()};");
                            IndexRollbacks.Add($"drop index {expectedTable.Table.Schema}.{index.IndexName};{Environment.NewLine}{actualIndex.DDL};");
                        }
                    }
                    else
                    {
                        IndexChanges.Add(index.ToDDL());
                        IndexRollbacks.Add($"drop index concurrently if exists {expectedTable.Table.Schema}.{index.IndexName};");
                    }
                });

                existing.ActualIndices.Values.Where(x => mapping.Indexes.All(_ => _.IndexName != x.Name)).Each(
                    index =>
                    {
                        IndexRollbacks.Add(index.DDL);
                        IndexChanges.Add($"drop index concurrently if exists {mapping.Table.Schema}.{index.Name};");
                    });

                var expectedFunction = new UpsertFunction(mapping);

                FunctionDiff = new FunctionDiff(expectedFunction.ToBody(rules), existing.Function);

                var missingFKs = mapping.ForeignKeys.Where(x => !existing.ForeignKeys.Contains(x.KeyName));
                MissingForeignKeys.AddRange(missingFKs);
            }

            _mapping = mapping;


        }
예제 #4
0
        public void WriteSchemaObjects(IDocumentSchema schema, StringWriter writer)
        {
            var table = StorageTable();
            var rules = schema.StoreOptions.DdlRules;

            table.Write(rules, writer);
            writer.WriteLine();
            writer.WriteLine();

            var function = new UpsertFunction(_mapping);

            function.WriteFunctionSql(rules, writer);


            _mapping.ForeignKeys.Each(x =>
            {
                writer.WriteLine();
                writer.WriteLine((string)x.ToDDL());
            });

            _mapping.Indexes.Each(x =>
            {
                writer.WriteLine();
                writer.WriteLine(x.ToDDL());
            });

            DependentScripts.Each(script =>
            {
                writer.WriteLine();
                writer.WriteLine();

                writer.WriteSql(_mapping.DatabaseSchemaName, script);
            });

            writer.WriteLine();
            writer.WriteLine();

            var template = _mapping.DdlTemplate.IsNotEmpty()
                ? rules.Templates[_mapping.DdlTemplate.ToLower()]
                : rules.Templates["default"];

            table.WriteTemplate(template, writer);
            var body = function.ToBody(rules);

            body.WriteTemplate(template, writer);

            writer.WriteLine();
            writer.WriteLine();
        }
예제 #5
0
        public SchemaDiff(SchemaObjects existing, DocumentMapping mapping, DdlRules rules)
        {
            if (existing.HasNone())
            {
                AllMissing = true;
            }
            else
            {
                var expectedTable = mapping.SchemaObjects.As <DocumentSchemaObjects>().StorageTable();
                TableDiff = new TableDiff(expectedTable, existing.Table);

                // TODO -- drop obsolete indices?

                mapping.Indexes.Each(index =>
                {
                    if (existing.ActualIndices.ContainsKey(index.IndexName))
                    {
                        var actualIndex = existing.ActualIndices[index.IndexName];
                        if (!index.Matches(actualIndex))
                        {
                            IndexChanges.Add($"drop index {expectedTable.Table.Schema}.{index.IndexName};{Environment.NewLine}{index.ToDDL()};");
                            IndexRollbacks.Add($"drop index {expectedTable.Table.Schema}.{index.IndexName};{Environment.NewLine}{actualIndex.DDL};");
                        }
                    }
                    else
                    {
                        IndexChanges.Add(index.ToDDL());
                        IndexRollbacks.Add($"drop index concurrently if exists {expectedTable.Table.Schema}.{index.IndexName};");
                    }
                });

                existing.ActualIndices.Values.Where(x => mapping.Indexes.All(_ => _.IndexName != x.Name)).Each(
                    index =>
                {
                    IndexRollbacks.Add(index.DDL);
                    IndexChanges.Add($"drop index concurrently if exists {mapping.Table.Schema}.{index.Name};");
                });

                var expectedFunction = new UpsertFunction(mapping);

                FunctionDiff = new FunctionDiff(expectedFunction.ToBody(rules), existing.Function);

                var missingFKs = mapping.ForeignKeys.Where(x => !existing.ForeignKeys.Contains(x.KeyName));
                MissingForeignKeys.AddRange(missingFKs);
            }

            _mapping = mapping;
        }
예제 #6
0
        public void WriteSchemaObjects(IDocumentSchema schema, StringWriter writer)
        {
            var table = StorageTable();

            table.Write(writer);
            writer.WriteLine();
            writer.WriteLine();

            var function = new UpsertFunction(_mapping);

            function.WriteFunctionSql(writer);


            _mapping.ForeignKeys.Each(x =>
            {
                writer.WriteLine();
                writer.WriteLine((string)x.ToDDL());
            });

            _mapping.Indexes.Each(x =>
            {
                writer.WriteLine();
                writer.WriteLine(x.ToDDL());
            });

            DependentScripts.Each(script =>
            {
                writer.WriteLine();
                writer.WriteLine();

                writer.WriteSql(_mapping.DatabaseSchemaName, script);
            });

            var ownerName = schema.StoreOptions.OwnerName;

            if (ownerName.IsNotEmpty())
            {
                writer.WriteLine($"ALTER TABLE {_mapping.Table} OWNER TO \"{ownerName}\";");

                var functionBody = function.ToBody();
                writer.WriteLine(functionBody.ToOwnershipCommand(ownerName));
            }

            writer.WriteLine();
            writer.WriteLine();
        }
예제 #7
0
        public DocumentSchema(DocumentMapping mapping)
        {
            _mapping = mapping;

            Table = new DocumentTable(_mapping);

            foreach (var metadataColumn in Table.Columns.OfType <MetadataColumn>())
            {
                metadataColumn.RegisterForLinqSearching(mapping);
            }

            Upsert = new UpsertFunction(_mapping);
            Insert = new InsertFunction(_mapping);
            Update = new UpdateFunction(_mapping);

            if (_mapping.UseOptimisticConcurrency)
            {
                Overwrite = new OverwriteFunction(_mapping);
            }
        }
예제 #8
0
        public virtual UpsertFunction ToUpsertFunction()
        {
            var function = new UpsertFunction(this);

            function.Arguments.AddRange(DuplicatedFields.Select(x => x.UpsertArgument));

            if (IsHierarchy())
            {
                function.Arguments.Add(new UpsertArgument
                {
                    Arg                = "docType",
                    Column             = DocumentTypeColumn,
                    DbType             = NpgsqlDbType.Varchar,
                    PostgresType       = "varchar",
                    BatchUpdatePattern = ".Param(_hierarchy.AliasFor(document.GetType()), NpgsqlDbType.Varchar)",
                    BulkInsertPattern  = "writer.Write(_hierarchy.AliasFor(x.GetType()), NpgsqlDbType.Varchar);"
                });
            }


            return(function);
        }
예제 #9
0
        private Action <BatchCommand.SprocCall, T, string, DocumentMapping, string> buildSprocWriter(DocumentMapping mapping)
        {
            var call         = Expression.Parameter(typeof(BatchCommand.SprocCall), "call");
            var doc          = Expression.Parameter(typeof(T), "doc");
            var json         = Expression.Parameter(typeof(string), "json");
            var mappingParam = Expression.Parameter(typeof(DocumentMapping), "mapping");
            var aliasParam   = Expression.Parameter(typeof(string), "alias");

            var arguments = new UpsertFunction(mapping).OrderedArguments().Select(x =>
            {
                return(x.CompileUpdateExpression(_serializer.EnumStorage, call, doc, json, mappingParam, aliasParam));
            });

            var block = Expression.Block(arguments);

            var lambda = Expression.Lambda <Action <BatchCommand.SprocCall, T, string, DocumentMapping, string> >(block,
                                                                                                                  new ParameterExpression[]
            {
                call, doc, json, mappingParam, aliasParam
            });


            return(lambda.Compile());
        }