public void WritePatch(IDocumentSchema schema, SchemaPatch patch) { var diff = CreateSchemaDiff(schema); if (!diff.HasDifferences()) { return; } if (diff.AllMissing) { patch.Rollbacks.Drop(this, _mapping.Table); WriteSchemaObjects(schema, patch.UpWriter); } else if (diff.CanPatch()) { diff.CreatePatch(schema.StoreOptions, patch); } if (schema.StoreOptions.OwnerName.IsNotEmpty()) { var ownership = $"ALTER TABLE {_mapping.Table} OWNER TO \"{schema.StoreOptions.OwnerName}\";"; patch.Updates.Apply(this, ownership); } }
public void GenerateSchemaObjectsIfNecessary(AutoCreate autoCreateSchemaObjectsMode, IDocumentSchema schema, SchemaPatch patch) { if (_checkedSchema) return; _checkedSchema = true; var tableExists = schema.DbObjects.TableExists(_parent.Table); if (tableExists) return; if (autoCreateSchemaObjectsMode == AutoCreate.None) { throw new InvalidOperationException( "The EventStore schema objects do not exist and the AutoCreateSchemaObjects is configured as " + autoCreateSchemaObjectsMode); } lock (_locker) { if (!schema.DbObjects.TableExists(_parent.Table)) { var writer = new StringWriter(); writeBasicTables(schema, writer); patch.Updates.Apply(this, writer.ToString()); } } }
public DocumentSchema(StoreOptions options, IConnectionFactory factory, IMartenLogger logger) { _factory = factory; _logger = logger; StoreOptions = options; options.AllDocumentMappings.Each(x => _mappings[x.DocumentType] = x); _sequences = new Lazy <SequenceFactory>(() => { var sequences = new SequenceFactory(this, _factory, options, _logger); var patch = new SchemaPatch(); sequences.GenerateSchemaObjectsIfNecessary(StoreOptions.AutoCreateSchemaObjects, this, patch); apply(sequences, patch); return(sequences); }); Parser = new MartenExpressionParser(StoreOptions.Serializer(), StoreOptions); HandlerFactory = new QueryHandlerFactory(this, options.Serializer()); DbObjects = new DbObjects(_factory, this); addSystemFunction(options, "mt_immutable_timestamp"); }
private void runDependentScripts(SchemaPatch runner) { DependentScripts.Each(script => { var sql = SchemaBuilder.GetSqlScript(_mapping.DatabaseSchemaName, script); runner.Updates.Apply(this, sql); }); }
private void writeOwnership(StoreOptions options, SchemaPatch patch) { if (options.OwnerName.IsEmpty()) return; var ownership = Expected.ToOwnershipCommand(options.OwnerName); patch.Updates.Apply(this, ownership); }
public void WritePatch(IDocumentSchema schema, SchemaPatch patch) { var diff = functionDiff(schema); if (diff.AllNew || !diff.Actual.Body.Contains(Body)) { diff.WritePatch(schema.StoreOptions, patch); } }
public void WritePatch(IDocumentSchema schema, SchemaPatch patch) { var diff = functionDiff(schema); if (diff.AllNew || diff.HasChanged) { diff.WritePatch(schema.StoreOptions, patch); } }
public void patch_if_it_does_not_exist() { var patch = new SchemaPatch(); theStore.Advanced.Options.Transforms.For("get_fullname") .WritePatch(theStore.Schema, patch); patch.UpdateDDL.ShouldContain("CREATE OR REPLACE FUNCTION public.mt_transform_get_fullname(doc JSONB) RETURNS JSONB AS $$"); }
public void CreatePatch(StoreOptions options, SchemaPatch patch) { TableDiff.CreatePatch(_mapping, patch); FunctionDiff.WritePatch(options, patch); IndexChanges.Each(x => patch.Updates.Apply(this, x)); IndexRollbacks.Each(x => patch.Rollbacks.Apply(this, x)); }
public SchemaPatch ToPatch(Type documentType) { var mapping = MappingFor(documentType); var patch = new SchemaPatch(StoreOptions.DdlRules); mapping.SchemaObjects.WritePatch(this, patch); return(patch); }
public void CreatePatch(StoreOptions options, SchemaPatch patch) { TableDiff.CreatePatch(_mapping, patch); FunctionDiff.WritePatch(options, patch); IndexChanges.Each(x => patch.Updates.Apply(this, x)); IndexRollbacks.Each(x => patch.Rollbacks.Apply(this, x)); }
private void rebuildTableAndUpsertFunction(IDocumentSchema schema, SchemaPatch runner) { var writer = new StringWriter(); WriteSchemaObjects(schema, writer); var sql = writer.ToString(); runner.Updates.Apply(this, sql); }
public void WritePatch(string filename, bool withSchemas = true) { var patch = ToPatch(withSchemas); patch.WriteUpdateFile(filename); var dropFile = SchemaPatch.ToDropFileName(filename); patch.WriteRollbackFile(dropFile); }
private void writeOwnership(StoreOptions options, SchemaPatch patch) { if (options.OwnerName.IsEmpty()) { return; } var ownership = Expected.ToOwnershipCommand(options.OwnerName); patch.Updates.Apply(this, ownership); }
public void WritePatch(DocumentMapping mapping, SchemaPatch patch) { patch.Updates.Apply(mapping, $"ALTER TABLE {mapping.Table.QualifiedName} ADD COLUMN {ColumnName} {PgType};"); var jsonField = new JsonLocatorField(_enumStorage, Members); // HOKEY, but I'm letting it pass for now. var sqlLocator = jsonField.SqlLocator.Replace("d.", ""); patch.Updates.Apply(mapping, $"update {mapping.Table.QualifiedName} set {ColumnName} = {sqlLocator};"); }
public void WritePatch(IDocumentSchema schema, SchemaPatch patch) { if (!_parent.IsActive) return; var tableExists = schema.DbObjects.TableExists(_parent.Table); if (tableExists) return; patch.Updates.Apply(this, SchemaBuilder.GetSqlScript(_parent.DatabaseSchemaName, "mt_stream")); patch.Rollbacks.Drop(this, new TableName(schema.Events.DatabaseSchemaName, "mt_streams")); }
public void WritePatch(string filename) { var patch = ToPatch(); var fileSystem = new FileSystem(); fileSystem.WriteStringToFile(filename, patch.UpdateDDL); var dropFile = SchemaPatch.ToDropFileName(filename); fileSystem.WriteStringToFile(dropFile, patch.RollbackDDL); }
public void ApplyAllConfiguredChangesToDatabase() { var patch = new SchemaPatch(this); var allSchemaNames = AllSchemaNames(); DatabaseSchemaGenerator.WriteSql(StoreOptions, allSchemaNames, patch.UpWriter); patch.Updates.Apply(this, patch.UpdateDDL); foreach (var schemaObject in AllSchemaObjects()) { schemaObject.GenerateSchemaObjectsIfNecessary(StoreOptions.AutoCreateSchemaObjects, this, patch); } }
public void WritePatch(string filename, bool withSchemas = true) { if (!Path.IsPathRooted(filename)) { filename = AppContext.BaseDirectory.AppendPath(filename); } var patch = ToPatch(withSchemas); patch.WriteUpdateFile(filename); var dropFile = SchemaPatch.ToDropFileName(filename); patch.WriteRollbackFile(dropFile); }
public TransformFunction TransformFor(string name) { return(_transforms.GetOrAdd(name, key => { var transform = StoreOptions.Transforms.For(key); var patch = new SchemaPatch(); transform.GenerateSchemaObjectsIfNecessary(StoreOptions.AutoCreateSchemaObjects, this, patch); apply(transform, patch); return transform; })); }
public void write_patch_with_designated_owner() { var func = new FunctionBody(new FunctionName("public", "mt_upsert_target"), new string[0], theFunctionBody); var patch = new SchemaPatch(); var options = new StoreOptions { OwnerName = "bill" }; var diff = new FunctionDiff(func, null); diff.WritePatch(options, patch); patch.UpdateDDL.ShouldContain("ALTER FUNCTION public.mt_upsert_target(jsonb, character varying, uuid, uuid) OWNER TO \"bill\";"); }
public void ApplyAllConfiguredChangesToDatabase() { var patch = new SchemaPatch(this); var allSchemaNames = AllSchemaNames(); DatabaseSchemaGenerator.WriteSql(StoreOptions, allSchemaNames, patch.UpWriter); patch.Updates.Apply(this, patch.UpdateDDL); foreach (var schemaObject in AllSchemaObjects()) { // Need to override the AutoCreate value here so stuff can actually work schemaObject.GenerateSchemaObjectsIfNecessary(AutoCreate.CreateOrUpdate, this, patch); } }
public SchemaPatch ToPatch(bool withSchemas = true) { var patch = new SchemaPatch(); if (withSchemas) { var allSchemaNames = AllSchemaNames(); DatabaseSchemaGenerator.WriteSql(StoreOptions, allSchemaNames, patch.UpWriter); } foreach (var schemaObject in AllSchemaObjects()) { schemaObject.WritePatch(this, patch); } return(patch); }
public void write_patch_without_designated_owner() { var func = new FunctionBody(new FunctionName("public", "mt_upsert_target"), new string[0], theFunctionBody); var patch = new SchemaPatch(); var options = new StoreOptions {OwnerName = null}; var diff = new FunctionDiff(func, null); diff.WritePatch(options, patch); patch.UpdateDDL.ShouldNotContain("OWNER TO"); }
public void GenerateSchemaObjectsIfNecessary(AutoCreate autoCreateSchemaObjectsMode, IDocumentSchema schema, SchemaPatch patch) { if (Checked) return; Checked = true; var diff = createFunctionDiff(schema); if (!diff.HasChanged) return; if (autoCreateSchemaObjectsMode == AutoCreate.None) { throw new InvalidOperationException($"{_function.QualifiedName} function is missing, but {nameof(StoreOptions.AutoCreateSchemaObjects)} is {autoCreateSchemaObjectsMode}"); } diff.WritePatch(schema.StoreOptions, patch); }
public void write_transactional_script_with_a_role() { var rules = new DdlRules(); rules.Role = "OCD_DBA"; var patch = new SchemaPatch(rules); var writer = new StringWriter(); patch.WriteTransactionalScript(writer, w => { w.WriteLine("Hello."); }); writer.ToString().ShouldContain("SET ROLE OCD_DBA;"); writer.ToString().ShouldContain("RESET ROLE;"); }
private void apply(object subject, SchemaPatch patch) { var ddl = patch.UpdateDDL.Trim(); if (ddl.IsEmpty()) { return; } try { _factory.RunSql(ddl); _logger.SchemaChange(ddl); } catch (Exception e) { throw new MartenSchemaException(subject, ddl, e); } }
public void can_patch_if_missing() { StoreOptions(_ => _.DatabaseSchemaName = "other"); using (var conn = theStore.Advanced.OpenConnection()) { conn.Execute( cmd => cmd.Sql("drop function if exists other.mt_immutable_timestamp(text)").ExecuteNonQuery()); } var function = new SystemFunction(theStore.Advanced.Options, "mt_immutable_timestamp", "text"); var patch = new SchemaPatch(new DdlRules()); function.WritePatch(theStore.Schema, patch); patch.UpdateDDL.ShouldContain("CREATE OR REPLACE FUNCTION other.mt_immutable_timestamp(value text)"); patch.RollbackDDL.ShouldContain("drop function if exists other.mt_immutable_timestamp"); }
public void WritePatch(IDocumentSchema schema, SchemaPatch patch) { var diff = CreateSchemaDiff(schema); if (!diff.HasDifferences()) { return; } if (diff.AllMissing) { patch.Rollbacks.Drop(this, _mapping.Table); WriteSchemaObjects(schema, patch.UpWriter); } else if (diff.CanPatch()) { diff.CreatePatch(schema.StoreOptions, patch); } }
public void EnsureStorageExists(Type documentType) { // TODO -- HACK! Do something later that's more systematic if (documentType == typeof(StreamState)) { return; } if (documentType == typeof(EventStream)) { var patch = new SchemaPatch(this); Events.SchemaObjects .GenerateSchemaObjectsIfNecessary(StoreOptions.AutoCreateSchemaObjects, this, patch); return; } buildSchemaObjectsIfNecessary(MappingFor(documentType)); }
private void buildOrModifySchemaObjects(SchemaDiff diff, AutoCreate autoCreateSchemaObjectsMode, IDocumentSchema schema, SchemaPatch runner) { if (autoCreateSchemaObjectsMode == AutoCreate.None) { var className = nameof(StoreOptions); var propName = nameof(StoreOptions.AutoCreateSchemaObjects); string message = $"No document storage exists for type {_mapping.DocumentType.FullName} and cannot be created dynamically unless the {className}.{propName} is greater than \"None\". See http://jasperfx.github.io/marten/documentation/documents/ for more information"; throw new InvalidOperationException(message); } if (diff.AllMissing) { rebuildAll(schema, runner); return; } if (autoCreateSchemaObjectsMode == AutoCreate.CreateOnly) { throw new InvalidOperationException( $"The table for document type {_mapping.DocumentType.FullName} is different than the current schema table, but AutoCreateSchemaObjects = '{nameof(AutoCreate.CreateOnly)}'"); } if (diff.CanPatch()) { diff.CreatePatch(schema.StoreOptions, runner); } else if (autoCreateSchemaObjectsMode == AutoCreate.All) { rebuildAll(schema, runner); } else { throw new InvalidOperationException( $"The table for document type {_mapping.DocumentType.FullName} is different than the current schema table, but AutoCreateSchemaObjects = '{autoCreateSchemaObjectsMode}'"); } runDependentScripts(runner); }
private void buildSchemaObjectsIfNecessary(IDocumentMapping mapping) { var sortedMappings = new[] { mapping }.TopologicalSort(x => { var documentMapping = x as DocumentMapping; if (documentMapping == null) { return(Enumerable.Empty <IDocumentMapping>()); } return(documentMapping.ForeignKeys .Select(keyDefinition => keyDefinition.ReferenceDocumentType) .Select(MappingFor)); }); var patch = new SchemaPatch(this); sortedMappings.Each( x => x.SchemaObjects.GenerateSchemaObjectsIfNecessary(StoreOptions.AutoCreateSchemaObjects, this, patch)); }
public void rebuilds_if_it_does_not_exist_in_the_schema_if_auto_create_is_all() { var schema = Substitute.For<IDocumentSchema>(); schema.StoreOptions.Returns(new StoreOptions()); var dbobjects = Substitute.For<IDbObjects>(); schema.DbObjects.Returns(dbobjects); var func = TransformFunction.ForFile(new StoreOptions {AutoCreateSchemaObjects = AutoCreate.All}, _getFullnameJs); dbobjects.SchemaFunctionNames().Returns(Enumerable.Empty<FunctionName>()); var patch = new SchemaPatch(new DdlRules()); func.GenerateSchemaObjectsIfNecessary(AutoCreate.All, schema, patch); var generated = func.GenerateFunction(); patch.UpdateDDL.ShouldContain(generated); }
public void WritePatch(StoreOptions options, SchemaPatch patch) { if (AllNew) { patch.Updates.Apply(this, Expected.Body); Expected.DropStatements.Each(drop => { if (!drop.EndsWith("cascade", StringComparison.OrdinalIgnoreCase)) { drop = drop.TrimEnd(';') + " cascade;"; } patch.Rollbacks.Apply(this, drop); }); writeOwnership(options, patch); } else if (HasChanged) { Actual.DropStatements.Each(drop => { if (!drop.EndsWith("cascade", StringComparison.OrdinalIgnoreCase)) { drop = drop.TrimEnd(';') + " cascade;"; } patch.Updates.Apply(this, drop); }); patch.Updates.Apply(this, Expected.Body); Expected.DropStatements.Each(drop => { patch.Rollbacks.Apply(this, drop); }); writeOwnership(options, patch); } }
public void CreatePatch(DocumentMapping mapping, SchemaPatch runner) { var systemFields = new string[] { DocumentMapping.LastModifiedColumn, DocumentMapping.DotNetTypeColumn, DocumentMapping.VersionColumn, DocumentMapping.DeletedColumn, DocumentMapping.DeletedAtColumn, DocumentMapping.DocumentTypeColumn }; var missingNonSystemFields = Missing.Where(x => !systemFields.Contains(x.Name)).ToArray(); var fields = missingNonSystemFields.Select(x => mapping.FieldForColumn(x.Name)).ToArray(); if (fields.Length != missingNonSystemFields.Length) { throw new InvalidOperationException("The expected columns did not match with the DocumentMapping"); } var missingSystemColumns = Missing.Where(x => systemFields.Contains(x.Name)).ToArray(); if (missingSystemColumns.Any()) { missingSystemColumns.Each(col => { var patch = $"alter table {_tableName.QualifiedName} add column {col.ToDeclaration(col.Name.Length + 1)};"; runner.Updates.Apply(this, patch); runner.Rollbacks.RemoveColumn(this, mapping.Table, col.Name); }); } fields.Each(x => { x.WritePatch(mapping, runner); runner.Rollbacks.RemoveColumn(this, mapping.Table, x.ColumnName); }); }
public void WritePatch(StoreOptions options, SchemaPatch patch) { if (AllNew) { patch.Updates.Apply(this, Expected.Body); Expected.DropStatements.Each(drop => { if (!drop.EndsWith("cascade", StringComparison.OrdinalIgnoreCase)) { drop = drop.TrimEnd(';') + " cascade;"; } patch.Rollbacks.Apply(this, drop); }); writeOwnership(options, patch); } else if (HasChanged) { Actual.DropStatements.Each(drop => { if (!drop.EndsWith("cascade", StringComparison.OrdinalIgnoreCase)) { drop = drop.TrimEnd(';') + " cascade;"; } patch.Updates.Apply(this, drop); }); patch.Updates.Apply(this, Expected.Body); Expected.DropStatements.Each(drop => { patch.Rollbacks.Apply(this, drop); }); writeOwnership(options, patch); } }
public void GenerateSchemaObjectsIfNecessary(AutoCreate autoCreateSchemaObjectsMode, IDocumentSchema schema, SchemaPatch patch) { if (_checked) return; var diff = functionDiff(schema); if (!diff.HasChanged) { _checked = true; return; } if (autoCreateSchemaObjectsMode == AutoCreate.None) { string message = $"The transform function {Function.QualifiedName} and cannot be created dynamically unless the {nameof(StoreOptions)}.{nameof(StoreOptions.AutoCreateSchemaObjects)} is higher than \"None\". See http://jasperfx.github.io/marten/documentation/documents/ for more information"; throw new InvalidOperationException(message); } diff.WritePatch(schema.StoreOptions, patch); }
public void WritePatchByType(string directory) { var system = new FileSystem(); system.DeleteDirectory(directory); system.CreateDirectory(directory); var schemaObjects = AllSchemaObjects().ToArray(); writeDatabaseSchemaGenerationScript(directory, system, schemaObjects); foreach (var schemaObject in schemaObjects) { var patch = new SchemaPatch(StoreOptions.DdlRules); schemaObject.WritePatch(this, patch); if (patch.UpdateDDL.IsNotEmpty()) { var file = directory.AppendPath(schemaObject.Name + ".sql"); patch.WriteUpdateFile(file); } } }
public void WritePatch(IDocumentSchema schema, SchemaPatch patch) { }
public void WritePatch(IDocumentSchema schema, SchemaPatch patch) { createFunctionDiff(schema).WritePatch(schema.StoreOptions, patch); }
private void rebuildAll(IDocumentSchema schema, SchemaPatch runner) { rebuildTableAndUpsertFunction(schema, runner); runDependentScripts(runner); }
public void GenerateSchemaObjectsIfNecessary(AutoCreate autoCreateSchemaObjectsMode, IDocumentSchema schema, SchemaPatch patch) { if (Checked) { return; } Checked = true; var diff = createFunctionDiff(schema); if (!diff.HasChanged) { return; } if (autoCreateSchemaObjectsMode == AutoCreate.None) { throw new InvalidOperationException($"{_function.QualifiedName} function is missing, but {nameof(StoreOptions.AutoCreateSchemaObjects)} is {autoCreateSchemaObjectsMode}"); } diff.WritePatch(schema.StoreOptions, patch); }
public void WritePatch(IDocumentSchema schema, SchemaPatch patch) { createFunctionDiff(schema).WritePatch(schema.StoreOptions, patch); }
public void throws_exception_if_auto_create_is_none_and_the_function_does_not_exist() { var schema = Substitute.For<IDocumentSchema>(); schema.StoreOptions.Returns(new StoreOptions()); var dbobjects = Substitute.For<IDbObjects>(); schema.DbObjects.Returns(dbobjects); var func = TransformFunction.ForFile(new StoreOptions { AutoCreateSchemaObjects = AutoCreate.None }, _getFullnameJs); dbobjects.SchemaFunctionNames().Returns(Enumerable.Empty<FunctionName>()); var patch = new SchemaPatch(new DdlRules()); Exception<InvalidOperationException>.ShouldBeThrownBy(() => { func.GenerateSchemaObjectsIfNecessary(AutoCreate.None, schema, patch); }); }
public void WritePatch(DocumentMapping mapping, SchemaPatch patch) { throw new NotSupportedException(); }
public void WritePatch(DocumentMapping mapping, SchemaPatch patch) { // Nothing }
public void WritePatch(DocumentMapping mapping, SchemaPatch patch) { // Nothing }
private void writeOwnership(StoreOptions options, SchemaPatch patch) { if (options.OwnerName.IsEmpty()) return; var toOwnershipDdl = createOwnershipDDL(options); patch.Updates.Apply(this, toOwnershipDdl); }
public void does_not_regenerate_the_function_if_it_exists() { var schema = Substitute.For<IDocumentSchema>(); var dbobjects = Substitute.For<IDbObjects>(); schema.DbObjects.Returns(dbobjects); var func = TransformFunction.ForFile(new StoreOptions(), _getFullnameJs); var body = new FunctionBody(func.Function, new string[0], func.GenerateFunction()); dbobjects.DefinitionForFunction(func.Function).Returns(body); var patch = new SchemaPatch(new DdlRules()); func.GenerateSchemaObjectsIfNecessary(AutoCreate.All, schema, patch); var generated = func.GenerateFunction(); patch.UpdateDDL.ShouldNotContain(generated); patch.RollbackDDL.ShouldNotContain(func.Function.QualifiedName); }
public void rebuilds_if_it_does_not_exist_in_the_schema_if_auto_create_is_create_or_update() { var schema = Substitute.For<IDocumentSchema>(); schema.StoreOptions.Returns(new StoreOptions()); var dbobjects = Substitute.For<IDbObjects>(); schema.DbObjects.Returns(dbobjects); var func = TransformFunction.ForFile(new StoreOptions { AutoCreateSchemaObjects = AutoCreate.CreateOrUpdate }, _getFullnameJs); dbobjects.SchemaFunctionNames().Returns(Enumerable.Empty<FunctionName>()); var patch = new SchemaPatch(new DdlRules()); func.GenerateSchemaObjectsIfNecessary(AutoCreate.CreateOrUpdate, schema, patch); var generated = func.GenerateFunction(); patch.UpdateDDL.ShouldContain(generated); patch.RollbackDDL.ShouldContain("DROP FUNCTION IF EXISTS public.mt_transform_get_fullname(JSONB)"); }
public void GenerateSchemaObjectsIfNecessary(AutoCreate autoCreateSchemaObjectsMode, IDocumentSchema schema, SchemaPatch patch) { }
public void WritePatch(DocumentMapping mapping, SchemaPatch patch) { patch.Updates.Apply(mapping, $"ALTER TABLE {mapping.Table.QualifiedName} ADD COLUMN {ColumnName} {PgType.Trim()};"); patch.UpWriter.WriteLine($"update {mapping.Table.QualifiedName} set {UpdateSqlFragment()};"); }
public void GenerateSchemaObjectsIfNecessary(AutoCreate autoCreateSchemaObjectsMode, IDocumentSchema schema, SchemaPatch patch) { if (_hasCheckedSchema || autoCreateSchemaObjectsMode == AutoCreate.None) { return; } DependentTypes.Each(schema.EnsureStorageExists); var diff = CreateSchemaDiff(schema); if (!diff.HasDifferences()) { _hasCheckedSchema = true; return; } lock (_lock) { if (_hasCheckedSchema) { return; } buildOrModifySchemaObjects(diff, autoCreateSchemaObjectsMode, schema, patch); _hasCheckedSchema = true; } }