private void buildOperationMethod(GeneratedType type, DocumentOperations operations, string methodName) { var operationType = (GeneratedType)typeof(DocumentOperations).GetProperty(methodName).GetValue(operations); var method = type.MethodFor(methodName); writeReturnOfOperation(method, operationType); }
private void buildStorageOperationMethods(DocumentOperations operations, GeneratedType type) { if (_mapping.UseOptimisticConcurrency) { buildConditionalOperationBasedOnConcurrencyChecks(type, operations, "Upsert"); buildOperationMethod(type, operations, "Insert"); buildOperationMethod(type, operations, "Overwrite"); buildConditionalOperationBasedOnConcurrencyChecks(type, operations, "Update"); } else { buildOperationMethod(type, operations, "Upsert"); buildOperationMethod(type, operations, "Insert"); buildOperationMethod(type, operations, "Update"); } if (_mapping.UseOptimisticConcurrency) { buildOperationMethod(type, operations, "Overwrite"); } else { type.MethodFor("Overwrite").Frames.ThrowNotSupportedException(); } }
public void AssembleTypes(GeneratedAssembly assembly) { var operations = new DocumentOperations(assembly, _mapping, _options); assembly.UsingNamespaces.Add(typeof(CommandExtensions).Namespace); assembly.UsingNamespaces.Add(typeof(TenantIdArgument).Namespace); assembly.UsingNamespaces.Add(typeof(NpgsqlCommand).Namespace); assembly.UsingNamespaces.Add(typeof(Weasel.Core.CommandExtensions).Namespace); var queryOnly = new DocumentStorageBuilder(_mapping, StorageStyle.QueryOnly, x => x.QueryOnlySelector) .Build(assembly, operations); var lightweight = new DocumentStorageBuilder(_mapping, StorageStyle.Lightweight, x => x.LightweightSelector) .Build(assembly, operations); var identityMap = new DocumentStorageBuilder(_mapping, StorageStyle.IdentityMap, x => x.IdentityMapSelector) .Build(assembly, operations); var dirtyTracking = new DocumentStorageBuilder(_mapping, StorageStyle.DirtyTracking, x => x.DirtyCheckingSelector) .Build(assembly, operations); var bulkWriterType = new BulkLoaderBuilder(_mapping).BuildType(assembly); buildProviderType(assembly, queryOnly, bulkWriterType, lightweight, identityMap, dirtyTracking); var types = new[] { typeof(IDocumentStorage <>), _mapping.DocumentType, _mapping.IdStrategy.GetType() }; assembly.Rules.ReferenceTypes(types); }
public DocumentProvider <T> Generate <T>() { var assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated")); var operations = new DocumentOperations(assembly, _mapping, _options); assembly.Namespaces.Add(typeof(CommandExtensions).Namespace); assembly.Namespaces.Add(typeof(TenantIdArgument).Namespace); assembly.Namespaces.Add(typeof(NpgsqlCommand).Namespace); var queryOnly = new DocumentStorageBuilder(_mapping, StorageStyle.QueryOnly, x => x.QueryOnlySelector) .Build(assembly, operations); var lightweight = new DocumentStorageBuilder(_mapping, StorageStyle.Lightweight, x => x.LightweightSelector) .Build(assembly, operations); var identityMap = new DocumentStorageBuilder(_mapping, StorageStyle.IdentityMap, x => x.IdentityMapSelector) .Build(assembly, operations); var dirtyTracking = new DocumentStorageBuilder(_mapping, StorageStyle.DirtyTracking, x => x.DirtyCheckingSelector) .Build(assembly, operations); var bulkWriterType = new BulkLoaderBuilder(_mapping).BuildType(assembly); var compiler = new AssemblyGenerator(); compiler.ReferenceAssembly(typeof(IDocumentStorage <>).Assembly); compiler.ReferenceAssembly(typeof(T).Assembly); compiler.Compile(assembly); var slot = new DocumentProvider <T> { QueryOnly = (IDocumentStorage <T>)Activator.CreateInstance(queryOnly.CompiledType, _mapping), Lightweight = (IDocumentStorage <T>)Activator.CreateInstance(lightweight.CompiledType, _mapping), IdentityMap = (IDocumentStorage <T>)Activator.CreateInstance(identityMap.CompiledType, _mapping), DirtyTracking = (IDocumentStorage <T>)Activator.CreateInstance(dirtyTracking.CompiledType, _mapping), Operations = operations, QueryOnlyType = queryOnly, LightweightType = lightweight, IdentityMapType = identityMap, DirtyTrackingType = dirtyTracking }; slot.BulkLoader = _mapping.IsHierarchy() ? (IBulkLoader <T>)Activator.CreateInstance(bulkWriterType.CompiledType, slot.QueryOnly, _mapping) : (IBulkLoader <T>)Activator.CreateInstance(bulkWriterType.CompiledType, slot.QueryOnly); slot.BulkLoaderType = bulkWriterType; return(slot); }
private void buildConditionalOperationBasedOnConcurrencyChecks(GeneratedType type, DocumentOperations operations, string methodName) { var operationType = (GeneratedType)typeof(DocumentOperations).GetProperty(methodName).GetValue(operations); var overwriteType = operations.Overwrite; var method = type.MethodFor(methodName); method.Frames.Code($"BLOCK:if (session.{nameof(IDocumentSession.Concurrency)} == {{0}})", ConcurrencyChecks.Disabled); writeReturnOfOperation(method, overwriteType); method.Frames.Code("END"); method.Frames.Code("BLOCK:else"); writeReturnOfOperation(method, operationType); method.Frames.Code("END"); }
private GeneratedType buildDocumentStorageType(GeneratedAssembly assembly, DocumentOperations operations, string typeName, Type baseType, GeneratedType selectorType) { var type = assembly.AddType(typeName, baseType); writeIdentityMethod(type); buildStorageOperationMethods(operations, type); type.MethodFor(nameof(ISelectClause.BuildSelector)) .Frames.Code($"return new Marten.Generated.{selectorType.TypeName}({{0}}, {{1}});", Use.Type <IMartenSession>(), Use.Type <DocumentMapping>()); buildLoaderCommands(type); writeNotImplementedStubs(type); return(type); }
private void buildStorageOperationMethods(DocumentOperations operations, GeneratedType type) { if (_mapping.UseOptimisticConcurrency) { buildConditionalOperationBasedOnConcurrencyChecks(type, operations, "Upsert"); buildOperationMethod(type, operations, "Insert"); buildOperationMethod(type, operations, "Overwrite"); buildConditionalOperationBasedOnConcurrencyChecks(type, operations, "Update"); } else { buildOperationMethod(type, operations, "Upsert"); buildOperationMethod(type, operations, "Insert"); buildOperationMethod(type, operations, "Update"); } if (_mapping.UseOptimisticConcurrency) { buildOperationMethod(type, operations, "Overwrite"); } else { type.MethodFor("Overwrite").Frames.ThrowNotSupportedException(); } type.MethodFor("DeleteForDocument").Frames.Code($@" return new Marten.Generated.{operations.DeleteById.TypeName}(Identity({{0}})); ", new Use(_mapping.DocumentType)); type.MethodFor("DeleteForId").Frames.Code($@" return new Marten.Generated.{operations.DeleteById.TypeName}({{0}}); ", new Use(_mapping.IdType)); type.MethodFor("DeleteForWhere").Frames.Code($@" return new Marten.Generated.{operations.DeleteByWhere.TypeName}({{0}}); ", Use.Type <IWhereFragment>()); }
public void AssemblyTypes(GeneratedAssembly assembly) { var operations = new DocumentOperations(assembly, _mapping, _options); assembly.Namespaces.Add(typeof(CommandExtensions).Namespace); assembly.Namespaces.Add(typeof(TenantIdArgument).Namespace); assembly.Namespaces.Add(typeof(NpgsqlCommand).Namespace); new DocumentStorageBuilder(_mapping, StorageStyle.QueryOnly, x => x.QueryOnlySelector) .Build(assembly, operations); new DocumentStorageBuilder(_mapping, StorageStyle.Lightweight, x => x.LightweightSelector) .Build(assembly, operations); new DocumentStorageBuilder(_mapping, StorageStyle.IdentityMap, x => x.IdentityMapSelector) .Build(assembly, operations); new DocumentStorageBuilder(_mapping, StorageStyle.DirtyTracking, x => x.DirtyCheckingSelector) .Build(assembly, operations); new BulkLoaderBuilder(_mapping).BuildType(assembly); }
public DocumentProvider <T> Generate <T>() { var assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated")); var operations = new DocumentOperations(assembly, _mapping, _options); assembly.Namespaces.Add(typeof(CommandExtensions).Namespace); assembly.Namespaces.Add(typeof(TenantIdArgument).Namespace); assembly.Namespaces.Add(typeof(NpgsqlCommand).Namespace); var queryOnly = new DocumentStorageBuilder(_mapping, StorageStyle.QueryOnly, x => x.QueryOnlySelector) .Build(assembly, operations); var lightweight = new DocumentStorageBuilder(_mapping, StorageStyle.Lightweight, x => x.LightweightSelector) .Build(assembly, operations); var identityMap = new DocumentStorageBuilder(_mapping, StorageStyle.IdentityMap, x => x.IdentityMapSelector) .Build(assembly, operations); var dirtyTracking = new DocumentStorageBuilder(_mapping, StorageStyle.DirtyTracking, x => x.DirtyCheckingSelector) .Build(assembly, operations); var bulkWriterType = new BulkLoaderBuilder(_mapping).BuildType(assembly); var compiler = new AssemblyGenerator(); compiler.ReferenceAssembly(typeof(IDocumentStorage <>).Assembly); compiler.ReferenceAssembly(typeof(T).Assembly); try { compiler.Compile(assembly); } catch (Exception e) { if (e.Message.Contains("is inaccessible due to its protection level")) { throw new InvalidOperationException($"Requested document type '{_mapping.DocumentType.FullNameInCode()}' must be either scoped as 'public' or the assembly holding it must use the {nameof(InternalsVisibleToAttribute)} pointing to 'Marten.Generated'", e); } throw; } var slot = new DocumentProvider <T> { QueryOnly = (IDocumentStorage <T>)Activator.CreateInstance(queryOnly.CompiledType, _mapping), Lightweight = (IDocumentStorage <T>)Activator.CreateInstance(lightweight.CompiledType, _mapping), IdentityMap = (IDocumentStorage <T>)Activator.CreateInstance(identityMap.CompiledType, _mapping), DirtyTracking = (IDocumentStorage <T>)Activator.CreateInstance(dirtyTracking.CompiledType, _mapping), Operations = operations, QueryOnlyType = queryOnly, LightweightType = lightweight, IdentityMapType = identityMap, DirtyTrackingType = dirtyTracking }; slot.BulkLoader = _mapping.IsHierarchy() ? (IBulkLoader <T>)Activator.CreateInstance(bulkWriterType.CompiledType, slot.QueryOnly, _mapping) : (IBulkLoader <T>)Activator.CreateInstance(bulkWriterType.CompiledType, slot.QueryOnly); slot.BulkLoaderType = bulkWriterType; return(slot); }
public GeneratedType Build(GeneratedAssembly assembly, DocumentOperations operations) { var selectorType = _selectorTypeSource(operations); return(buildDocumentStorageType(assembly, operations, _typeName, _baseType, selectorType)); }
public DocumentProvider <T> Generate <T>() { var assembly = new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace)); var operations = new DocumentOperations(assembly, _mapping, _options); assembly.Namespaces.Add(typeof(CommandExtensions).Namespace); assembly.Namespaces.Add(typeof(Weasel.Core.CommandExtensions).Namespace); assembly.Namespaces.Add(typeof(TenantIdArgument).Namespace); assembly.Namespaces.Add(typeof(NpgsqlCommand).Namespace); var queryOnly = new DocumentStorageBuilder(_mapping, StorageStyle.QueryOnly, x => x.QueryOnlySelector) .Build(assembly, operations); var lightweight = new DocumentStorageBuilder(_mapping, StorageStyle.Lightweight, x => x.LightweightSelector) .Build(assembly, operations); var identityMap = new DocumentStorageBuilder(_mapping, StorageStyle.IdentityMap, x => x.IdentityMapSelector) .Build(assembly, operations); var dirtyTracking = new DocumentStorageBuilder(_mapping, StorageStyle.DirtyTracking, x => x.DirtyCheckingSelector) .Build(assembly, operations); var bulkWriterType = new BulkLoaderBuilder(_mapping).BuildType(assembly); var compiler = new AssemblyGenerator(); var types = new[] { typeof(IDocumentStorage <>), typeof(T), }; foreach (var referencedAssembly in WalkReferencedAssemblies.ForTypes(types)) { compiler.ReferenceAssembly(referencedAssembly); } var providerType = assembly.AddType(ProviderName, typeof(DocumentProvider <>).MakeGenericType(_mapping.DocumentType)); providerType.AllInjectedFields.Clear(); providerType.AllInjectedFields.Add(new InjectedField(typeof(DocumentMapping), "mapping")); var bulkWriterArgType = typeof(IBulkLoader <>).MakeGenericType(_mapping.DocumentType); var bulkWriterArgs = $"new {queryOnly.TypeName}(mapping)"; if (bulkWriterType.AllInjectedFields.Count == 2) { bulkWriterArgs += ", mapping"; } var bulkWriterCode = $"new {bulkWriterType.TypeName}({bulkWriterArgs})"; providerType.BaseConstructorArguments[0] = new Variable(bulkWriterArgType, bulkWriterCode); providerType.BaseConstructorArguments[1] = new CreateFromDocumentMapping(_mapping, typeof(IDocumentStorage <>), queryOnly); providerType.BaseConstructorArguments[2] = new CreateFromDocumentMapping(_mapping, typeof(IDocumentStorage <>), lightweight); providerType.BaseConstructorArguments[3] = new CreateFromDocumentMapping(_mapping, typeof(IDocumentStorage <>), identityMap); providerType.BaseConstructorArguments[4] = new CreateFromDocumentMapping(_mapping, typeof(IDocumentStorage <>), dirtyTracking); try { compiler.Compile(assembly); } catch (Exception e) { if (e.Message.Contains("is inaccessible due to its protection level")) { throw new InvalidOperationException($"Requested document type '{_mapping.DocumentType.FullNameInCode()}' must be either scoped as 'public' or the assembly holding it must use the {nameof(InternalsVisibleToAttribute)} pointing to 'Marten.Generated'", e); } throw; } return((DocumentProvider <T>)Activator.CreateInstance(providerType.CompiledType, _mapping)); }