public static (EventDocumentStorage, string) GenerateStorage(StoreOptions options)
        {
            var assembly = new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace));

            assembly.ReferenceAssembly(typeof(EventGraph).Assembly);

            var builderType = assembly.AddType(EventDocumentStorageTypeName, typeof(EventDocumentStorage));

            buildSelectorMethods(options, builderType);

            var appendType = buildAppendEventOperation(options.EventGraph, assembly);

            builderType.MethodFor(nameof(EventDocumentStorage.AppendEvent))
            .Frames.Code($"return new Marten.Generated.AppendEventOperation(stream, e);");

            var insertType = buildInsertStream(builderType, assembly, options.EventGraph);

            var streamQueryHandlerType = buildStreamQueryHandlerType(options.EventGraph, assembly);

            buildQueryForStreamMethod(options.EventGraph, builderType);

            var updateType = buildUpdateStreamVersion(builderType, assembly, options.EventGraph);


            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IMartenSession).Assembly);
            compiler.Compile(assembly);


            var writer = new StringWriter();

            writer.WriteLine($"    // {streamQueryHandlerType.TypeName}");
            writer.WriteLine(streamQueryHandlerType.SourceCode);
            writer.WriteLine();

            writer.WriteLine($"    // {insertType.TypeName}");
            writer.WriteLine(insertType.SourceCode);
            writer.WriteLine();

            writer.WriteLine($"    // {appendType.TypeName}");
            writer.WriteLine(appendType.SourceCode);
            writer.WriteLine();

            writer.WriteLine($"    // {updateType.TypeName}");
            writer.WriteLine(updateType.SourceCode);
            writer.WriteLine();

            writer.WriteLine($"    // {builderType.TypeName}");
            writer.WriteLine(builderType.SourceCode);
            writer.WriteLine();



            var code = writer.ToString();

            var storage = (EventDocumentStorage)Activator.CreateInstance(builderType.CompiledType, options);

            return(storage, code);
        }
Пример #2
0
        internal void Compile()
        {
            _assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            _assembly.Generation.Assemblies.Add(GetType().Assembly);
            _assembly.Generation.Assemblies.AddRange(_projectMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_createMethods.ReferencedAssemblies());

            _assembly.Namespaces.Add("System.Linq");

            _isAsync = _createMethods.IsAsync || _projectMethods.IsAsync;

            var baseType = _isAsync ? typeof(AsyncEventProjection <>) : typeof(SyncEventProjection <>);

            baseType    = baseType.MakeGenericType(GetType());
            _inlineType = _assembly.AddType(GetType().Name.Sanitize() + "GeneratedInlineProjection", baseType);

            var method = _inlineType.MethodFor("ApplyEvent");

            method.DerivedVariables.Add(new Variable(GetType(), "Projection"));

            var eventHandling = MethodCollection.AddEventHandling(null, null, _createMethods, _projectMethods);

            method.Frames.Add(eventHandling);

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(_assembly);
        }
        public static (EventDocumentStorage, string) GenerateStorage(StoreOptions options)
        {
            var assembly    = new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace));
            var builderType = AssembleTypes(options, assembly);


            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IMartenSession).Assembly);
            compiler.Compile(assembly);


            var writer = new StringWriter();

            foreach (var generatedType in assembly.GeneratedTypes)
            {
                writer.WriteLine($"    // {generatedType.TypeName}");
                writer.WriteLine(generatedType.SourceCode);
                writer.WriteLine();
            }



            var code = writer.ToString();

            var storage = (EventDocumentStorage)Activator.CreateInstance(builderType.CompiledType, options);

            return(storage, code);
        }
Пример #4
0
        internal GeneratedAssembly Compile(DocumentStore store)
        {
            _assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            _assembly.Generation.Assemblies.Add(GetType().Assembly);
            _assembly.Generation.Assemblies.AddRange(_applyMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_createMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_shouldDeleteMethods.ReferencedAssemblies());

            _assembly.Namespaces.Add("System.Linq");

            _isAsync = _createMethods.IsAsync || _applyMethods.IsAsync;

            _aggregateMapping = store.Storage.MappingFor(typeof(T));
            _storageType      = typeof(IDocumentStorage <,>).MakeGenericType(typeof(T), _aggregateMapping.IdType);


            // TODO -- Validate the id strategy for the mapping
            // against the aggregation setup


            buildLiveAggregationType();
            buildInlineAggregationType();
            buildAsyncDaemonAggregation();

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(_assembly);

            return(_assembly);
        }
Пример #5
0
        public static EventDocumentStorage GenerateStorage(StoreOptions options)
        {
            var assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            assembly.ReferenceAssembly(typeof(EventGraph).Assembly);

            var builderType = assembly.AddType("GeneratedEventDocumentStorage", typeof(EventDocumentStorage));

            buildSelectorMethods(options, builderType);

            buildAppendEventOperation(options.Events, assembly);

            builderType.MethodFor(nameof(EventDocumentStorage.AppendEvent))
            .Frames.Code($"return new Marten.Generated.AppendEventOperation(stream, e);");

            buildInsertStream(builderType, assembly, options.Events);

            var streamQueryHandlerType = buildStreamQueryHandlerType(options.Events, assembly);

            buildQueryForStreamMethod(options.Events, builderType);

            buildUpdateStreamVersion(builderType, assembly, options.Events);


            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IMartenSession).Assembly);
            compiler.Compile(assembly);

            var code = streamQueryHandlerType.SourceCode;

            return((EventDocumentStorage)Activator.CreateInstance(builderType.CompiledType, options));
        }
Пример #6
0
        private void compileAssembly(GeneratedAssembly assembly)
        {
            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IDocumentStorage <>).Assembly);
            compiler.ReferenceAssembly(_plan.QueryType.Assembly);
            compiler.ReferenceAssembly(_plan.OutputType.Assembly);

            compiler.Compile(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);

            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);
        }
Пример #8
0
        internal static ILiveAggregator <T> Build <T>(StoreOptions options)
        {
            var mapping = options.Storage.MappingFor(typeof(T));

            var assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            var applyMethods = new ApplyMethodCollection(typeof(T), typeof(T));

            // TODO -- this doesn't do very much right now.
            var createMethods = new CreateMethodCollection(typeof(T), typeof(T));

            assembly.Generation.Assemblies.Add(typeof(IMartenSession).Assembly);
            assembly.Generation.Assemblies.AddRange(applyMethods.ReferencedAssemblies());
            assembly.Generation.Assemblies.AddRange(createMethods.ReferencedAssemblies());

            var isAsync = applyMethods.IsAsync;

            assembly.Namespaces.Add("System.Linq");

            var liveBaseType = isAsync
                ? typeof(AsyncLiveAggregatorBase <>)
                : typeof(SyncLiveAggregatorBase <>);

            liveBaseType = liveBaseType.MakeGenericType(typeof(T));

            var liveType = assembly.AddType(typeof(T).NameInCode().Sanitize() + "LiveAggregation", liveBaseType);

            var overrideMethodName = isAsync ? "BuildAsync" : "Build";
            var buildMethod        = liveType.MethodFor(overrideMethodName);

            // TODO -- use constructor functions later
            // TODO -- use static Create() methods
            // TODO -- validate that there is some way to create the aggregate
            buildMethod.Frames.Code("if (!events.Any()) return null;");
            buildMethod.Frames.Add(new CallCreateAggregateFrame(createMethods));
            buildMethod.Frames.Add(new CallApplyAggregateFrame(applyMethods)
            {
                InsideForEach = true
            });

            buildMethod.Frames.Return(typeof(T));

            createMethods.BuildCreateMethod(liveType, mapping);
            applyMethods.BuildApplyMethod(liveType, mapping);

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(assembly);

            return((ILiveAggregator <T>)Activator.CreateInstance(liveType.CompiledType));
        }
        private void compileAssembly(GeneratedAssembly assembly)
        {
            var compiler = new AssemblyGenerator();

            foreach (var referencedAssembly in walkReferencedAssemblies(
                         typeof(IDocumentStorage <>),
                         _plan.QueryType,
                         _plan.OutputType))
            {
                compiler.ReferenceAssembly(referencedAssembly);
            }

            compiler.Compile(assembly);
        }
Пример #10
0
        /// <summary>
        ///     Only for testing support
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public static EventDocumentStorage GenerateStorage(StoreOptions options)
        {
            var assembly =
                new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace + ".EventStore"));
            var builderType = AssembleTypes(options, assembly);


            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IMartenSession).Assembly);
            compiler.Compile(assembly);


            return((EventDocumentStorage)Activator.CreateInstance(builderType.CompiledType, options));
        }
        internal GeneratedAssembly Compile(StoreOptions options)
        {
            var assembly = new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace));

            AssembleTypes(assembly, options);

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(assembly);

            _liveType   = _liveGeneratedType.CompiledType;
            _inlineType = _inlineGeneratedType.CompiledType;

            return(assembly);
        }
Пример #12
0
        internal GeneratedAssembly Compile(StoreOptions options)
        {
            _assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            _assembly.Generation.Assemblies.Add(GetType().Assembly);
            _assembly.Generation.Assemblies.Add(typeof(T).Assembly);
            _assembly.Generation.Assemblies.AddRange(_applyMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_createMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_shouldDeleteMethods.ReferencedAssemblies());

            _assembly.Namespaces.Add("System");
            _assembly.Namespaces.Add("System.Linq");

            _isAsync = _createMethods.IsAsync || _applyMethods.IsAsync;

            _aggregateMapping = options.Storage.MappingFor(typeof(T));


            if (_aggregateMapping.IdMember == null)
            {
                // TODO -- possibly try to relax this!!!
                throw new InvalidDocumentException(
                          $"No identity property or field can be determined for the aggregate '{typeof(T).FullNameInCode()}', but one is required to be used as an aggregate in projections");
            }

            _storageType = typeof(IDocumentStorage <,>).MakeGenericType(typeof(T), _aggregateMapping.IdType);


            // TODO -- Validate the id strategy for the mapping
            // against the aggregation setup


            buildLiveAggregationType();
            buildInlineAggregationType();

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(_assembly);

            Debug.WriteLine(_liveType.SourceCode);

            return(_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 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));
        }