示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#5
0
        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");
        }
示例#6
0
        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);
        }
示例#10
0
        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));
        }