public EventStoreProjectorRegistry(ILoggerFactory loggerFactory , EventStoreConnectionProvider connectionProvider , IServiceProvider serviceProvider , IEntityStore entityStore , ICacheClient cache , IOptions <ProjectionOptions> options ) { if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); _connectionProvider = connectionProvider ?? throw new ArgumentNullException(nameof(connectionProvider)); _logger = loggerFactory.CreateLogger(GetType()); _projectors = serviceProvider.GetServices <IReadModelProjector>(); _entityStore = entityStore ?? throw new ArgumentNullException(nameof(entityStore)); _cache = cache ?? throw new ArgumentNullException(nameof(cache)); _options = options.Value; }
/// <summary> /// Appends the equality operator to the current projection buffer and changes the projection separator value to <c>,</c>. /// </summary> /// <param name="projection">The current projection.</param> /// <returns>A new projection containing the appended buffer.</returns> public static IProjection Eq(this IProjection projection) { ProjectionOptions newOptions = new ProjectionOptions(projection.Options) { Separator = "," + Environment.NewLine, }; return(projection.Map(a => a.Eq()).With(options: newOptions)); }
public MapperOptions() { Strictness = new MapperStrictnessOptions { ThrowWithoutCorrespondingSourceMember = false }; Conventions = new MapperConventionOptions { CallToStringWhenDestinationIsString = true, AutomaticallyFlattenHierarchies = true, MakeCloneIfDestinationIsTheSameAsSource = true, IgnoreMemberAttributeShouldBeRespected = true, ReuseNonNullComplexMembersOnDestination = true, IgnoreCaseWhenFindingMatch = true, IgnoreMembersWithNullValueOnSource = false, PreserveDestinationListContents = true, MaxDepth = null }; Safety = new MapperSafetyOptions { PerformNullChecksOnCustomMappings = true, IfSourceIsNull = SourceObjectNullOptions.ReturnNullWhenSourceIsNull, IfRecursiveRelationshipIsDetected = RecursivePropertyOptions.IgnoreRecursiveProperties, ThrowIfDestinationIsNull = true, EnsureCollectionIsNotArrayType = true, UseDefaultValueForMissingVariable = true }; Compilation = new CompilationOptions { CompileToDynamicAssembly = true }; Projection = new ProjectionOptions { MapCollectionMembers = true }; Cloning = new CloneOptions { MaxCloneDepth = 2, }; Debug = new DebugOptions { #if DEBUG DebugInformationEnabled = true #else DebugInformationEnabled = false #endif }; } }
public async Task <IActionResult> GetAsync([FromRoute][BindRequired] TKey id, FieldOptions fields, ProjectionOptions projections) { var @object = await _repository.GetAsync(id, fields); if (@object?.Data == null) { return(NotFound()); } Response.MaybeEnvelope(Request, _apiOptions.CurrentValue.JsonConversion, @object.Data, @object.Errors, out var body); return(Ok(body)); }
public static string Select <T>(ISqlDialect dialect, FieldOptions fields, ProjectionOptions projections) { return(StringBuilderPool.Scoped(sb => { // SELECT * FROM ... sb.Append($"SELECT {BuildFields<T>(dialect, fields, projections)} " + $"FROM {dialect.StartIdentifier}{typeof(T).Name}{dialect.EndIdentifier} r "); if (projections?.Fields == null) { return; } // INNER JOIN... var joins = 0; foreach (var projection in projections.Fields) { var name = projection.Field.ToTitleCase(); if (name.EndsWith("s")) { name = name.Substring(0, name.Length - 1); } switch (projection.Type) { case ProjectionType.OneToOne: /* * INNER JOIN Role r0 ON r0.Id = x0.RoleId */ sb.Append($"INNER JOIN {name} r{joins} ON r{joins}.Id = x{joins}.{name}Id "); break; case ProjectionType.OneToMany: /* * INNER JOIN UserRole x0 ON x0.UserId = r.Id * INNER JOIN Role r0 ON r0.Id = x0.RoleId */ sb.Append( $"INNER JOIN {typeof(T).Name}{name} x{joins} ON x{joins}.{typeof(T).Name}Id = r.Id "); sb.Append($"INNER JOIN {name} r{joins} ON r{joins}.Id = x{joins}.{name}Id "); break; case ProjectionType.Scalar: break; default: throw new ArgumentOutOfRangeException(); } joins++; } })); }
public ProjectionAssembly(string name, ProjectionOptions options) { this.name = name; assembly = AppDomain.CurrentDomain.DefineDynamicAssembly ( new AssemblyName(name), GetAssemblyAccess(options) ); module = 0 == (options & ProjectionOptions.SaveAssemblies) ? assembly.DefineDynamicModule(name) : assembly.DefineDynamicModule(name, FileName); }
public async Task <Operation <TObject> > GetAsync(long id, FieldOptions fields = null, ProjectionOptions projection = null) { _db.SetTypeInfo(typeof(TObject)); var getById = FilterOptions.FromType <TObject>(x => x.Id); getById.Fields[0].Value = id; var sql = _dialect.Build <TObject>(fields: fields, filter: getById, projections: projection); var data = await _db.Current.QuerySingleOrDefaultAsync <TObject>(sql, new { id }); return(new Operation <TObject>(data)); }
/// <summary> /// Adds an underlay registration to the database. /// </summary> /// <param name="definition">optional satellite definition used to generate underlay</param> /// <param name="options">underlay rendering options</param> /// <param name="filename">filename of rendered underlay</param> public async Task RegisterCacheAsync(SatelliteDefinition?definition, ProjectionOptions options, string filename) { await using var connection = new SqliteConnection(ConnectionString); await connection.OpenAsync(); string sql = definition == null ? "INSERT INTO UnderlayCache(Filename, Configuration) VALUES(@Filename, @Configuration)" : "INSERT INTO UnderlayCache(Filename, Configuration, Longitude) VALUES(@Filename, @Configuration, @Longitude)"; await connection.ExecuteAsync(sql, new { Filename = filename, Configuration = JsonConvert.SerializeObject(options), definition?.Longitude }); }
public FieldsToFetch(IndexQueryServerSide query, IndexDefinitionBaseServerSide indexDefinition) { Projection = new ProjectionOptions(query); Fields = GetFieldsToFetch(query.Metadata, query.ProjectionBehavior, indexDefinition, out AnyExtractableFromIndex, out bool extractAllStoredFields, out SingleBodyOrMethodWithNoAlias, out AnyTimeSeries); IsProjection = Fields != null && Fields.Count > 0; IndexFields = indexDefinition?.IndexFields; AnyDynamicIndexFields = indexDefinition != null && indexDefinition.HasDynamicFields; if (extractAllStoredFields) { AnyExtractableFromIndex = true; ExtractAllFromIndex = true; // we want to add dynamic fields also to the result (stored only) IsProjection = true; } IsDistinct = query.Metadata.IsDistinct && IsProjection; }
public static string Build <T>(this ISqlDialect dialect, SortOptions sort = null, FieldOptions fields = null, FilterOptions filter = null, ProjectionOptions projections = null) { return(StringBuilderPool.Scoped(sb => { // SELECT * FROM ... sb.Append(ProjectionBuilder.Select <T>(dialect, fields, projections)); // WHERE ... if (filter?.Fields.Count > 0) { sb.Append($" {dialect.Where(filter)}"); } // ORDER BY ... if (sort?.Fields.Count > 0) { sb.Append($" {SortingBuilder.OrderBy(dialect, sort)}"); } })); }
public static IProjection IsEq(this IProjection projection, IProjection other) { List <IProjectionAttribute> newHeader = new List <IProjectionAttribute>(); foreach (var(l, r) in projection.Attrs().Zip(other.Attrs())) { IProjectionAttribute newAttr = l; newAttr = newAttr.Eq(); newAttr = newAttr.With(data: r.Data).Par(); newAttr = newAttr.With(data: l.Data); newHeader.Add(newAttr); } ProjectionOptions newOptions = new ProjectionOptions(projection.Options) { Separator = Environment.NewLine + "AND" + Environment.NewLine, }; return(projection.With(header: newHeader, options: newOptions)); }
public static IProjection IsEq(this IProjection projection, IProjection other) { List <IProjectionAttribute> newAttrs = new List <IProjectionAttribute>(); foreach (var(l, r) in projection.Attrs().Zip(other.Attrs())) { IProjectionAttribute newAttr = l; newAttr = newAttr.Eq(); newAttr = newAttr.With(metadata: r.Metadata, field: r.Field).Par(); newAttr = newAttr.With(metadata: l.Metadata, field: l.Field); newAttrs.Add(newAttr); } ProjectionOptions newOptions = new ProjectionOptions(projection.Options) { Separator = Environment.NewLine + "AND" + Environment.NewLine, }; return(projection.With(attributes: newAttrs, options: newOptions)); }
private static string BuildFields(this ISqlDialect dialect, Type type, FieldOptions options, ProjectionOptions projections) { var source = BuildFieldSource(type, options); return(Pooling.StringBuilderPool.Scoped(sb => { sb.Append(string.Join(", ", source.Select(a => $"r.{dialect.StartIdentifier}{a}{dialect.EndIdentifier}"))); if (projections?.Fields == null) { return; } var joins = 0; foreach (var projection in projections.Fields) { sb.Append($", r{joins}.*"); joins++; } })); }
public void Execute(ISqlPage page) { var proc = (ProcPage <IRunnable, object>)page; foreach (ActionItem a in this.actions) { if (a.Sql != null) { proc.WriteLiteral(a.Sql); } if (a.Result != null) { proc.Write(a.Result(WithOptions(proc.R))); } if (a.Model != null) { proc.Write(a.Model(WithOptions(proc.M))); } } IProjection WithOptions(IProjection projection) { if (this.Separator == null) { return(projection); } var newOptions = new ProjectionOptions(projection.Options) { Separator = this.Separator }; return(projection.With(options: newOptions)); } }
private static AssemblyBuilderAccess GetAssemblyAccess(ProjectionOptions options) { switch (options & ProjectionOptionsInternal.AssemblyModes) { default: case ProjectionOptions.None: return AssemblyBuilderAccess.Run; case ProjectionOptions.SaveAssemblies: return AssemblyBuilderAccess.RunAndSave; case ProjectionOptions.CollectAssemblies: return AssemblyBuilderAccess.RunAndCollect; } }
public virtual async Task <IStream <Person> > GetAsync(IEnumerable <long> ids = null, long startingAt = 0, int?count = null, FieldOptions fields = null, FilterOptions filter = null, ProjectionOptions projection = null) { var operation = await _repository.GetAsync(ids, startingAt, count, fields, filter, projection); return(operation.Data); }
public virtual async Task <Person> GetAsync(long id, FieldOptions fields = null, ProjectionOptions projection = null) { var operation = await _repository.GetAsync(id, fields, projection); return(operation.Data); }
/// <summary> /// Sets an underlay image to the cache. /// </summary> public async Task SetUnderlayAsync(Image <Rgba32> underlay, SatelliteDefinition?definition, ProjectionOptions options) { if (definition == null) { _logger.LogInformation("Caching underlay"); } else { _logger.LogInformation("{definition:l0} Caching underlay", definition.DisplayName); } // Save underlay to disk var filename = $"{Guid.NewGuid()}.jpg"; await underlay.SaveAsync(Path.Combine(_cachePath, filename)); // Register underlay path in the cache await _repository.RegisterCacheAsync(definition, options, filename); }
public SingleFactory(ProjectionOptions options) : base(options) { var name = GenerateAssemblyName(NamePrefix, NameSuffixLength); assembly = CreateProjectionAssembly(name); }
protected ProjectionAssemblyFactory(ProjectionOptions options) { this.options = options; this.unsaved = new CellList<ProjectionAssembly>(); }
public static ProjectionAssemblyFactory PerType(ProjectionOptions options) { return new PerTypeFactory(options); }
public PerTypeFactory(ProjectionOptions options) : base(options) { }
public virtual async Task <Operation <Person> > GetAsync(long id, FieldOptions fields = null, ProjectionOptions projection = null) { _db.SetTypeInfo(typeof(Person)); var getById = DefaultFilter; getById.Fields[0].Value = id; var sql = _dialect.Build <Person>(fields: fields, filter: DefaultFilter, projections: projection); var data = await _db.Current.QuerySingleOrDefaultAsync <Person>(sql, new { id }); return(new Operation <Person>(data)); }
public static ProjectionOptions Set(this ProjectionOptions options, ProjectionOptions flag, bool value) { return value ? options | flag : options & ~flag; }
public ProjectionConfiguration EnableSaveAssemblies(bool enabled) { options = options.Set(ProjectionOptions.SaveAssemblies, enabled); return this; }
public ProjectionConfiguration EnableSaveAssemblies() { options = options.Set(ProjectionOptions.SaveAssemblies, true); return this; }
public virtual async Task <IActionResult> GetAsync([FromRoute, BindRequired] long id, FieldOptions fields, ProjectionOptions projection) { var @object = await _repository.GetAsync(id, fields); if (@object?.Data == null) { return(NotFound()); } Response.MaybeEnvelope(Request, _apiOptions.Value, _queryOptions.Value, @object.Data, @object.Errors, out var body); return(Ok(body)); }
public static string Build <T>(this ISqlDialect dialect, SortOptions sort = null, FieldOptions fields = null, FilterOptions filter = null, ProjectionOptions projections = null) { return(Build(dialect, typeof(T), sort, fields, filter, projections)); }
public virtual async Task <IActionResult> GetAsync(SortOptions sort, PageOptions page, StreamOptions stream, FieldOptions fields, FilterOptions filter, ProjectionOptions projection, [FromQuery] IEnumerable <long> ids = null, [FromQuery] string query = null, [FromQuery] long startingAt = 0, [FromQuery] int?count = null) { // ReSharper disable once PossibleMultipleEnumeration if (ids != null && (count.HasValue && count > 0 || ids.Any())) { // ReSharper disable once PossibleMultipleEnumeration var slice = await _repository.GetAsync(ids, startingAt, count, fields, filter, projection); if (slice?.Data?.Count == 0) { return(NotFound()); } Response.MaybeEnvelope(Request, _apiOptions.Value, _queryOptions.Value, slice?.Data, slice?.Errors, out var body); return(Ok(body)); } else { var slice = await _repository.GetAsync(query, sort, page, fields, filter, projection); if (slice?.Data?.Count == 0) { return(NotFound()); } Response.MaybeEnvelope(Request, _apiOptions.Value, _queryOptions.Value, slice?.Data, slice?.Errors, out var body); return(Ok(body)); } }
public static ProjectionAssemblyFactory Single(ProjectionOptions options) { return new SingleFactory(options); }
public async Task <IActionResult> GetAsync(SortOptions sort, PageOptions page, StreamOptions stream, FieldOptions fields, FilterOptions filter, ProjectionOptions projection, SegmentOptions segment, [FromQuery] string query = null) { // ReSharper disable once PossibleMultipleEnumeration if (segment.Ids != null && (segment.Count > 0 || segment.Ids.Any())) { // ReSharper disable once PossibleMultipleEnumeration var slice = await _repository.GetAsync(segment, fields, filter, projection); Response.MaybeEnvelope(Request, _apiOptions.CurrentValue.JsonConversion, slice?.Data, slice?.Errors, out var body); return(Ok(body)); } else { var slice = await _repository.GetAsync(query, sort, page, fields, filter, projection); Response.MaybeEnvelope(Request, _apiOptions.CurrentValue.JsonConversion, slice?.Data, slice?.Errors, out var body); return(Ok(body)); } }
public static ProjectionAssemblyFactory Batched(int limit, ProjectionOptions options) { return new BatchedFactory(limit, options); }
/// <summary> /// Retrieves a cached underlay filename based on an optional satellite definition and render options, or /// <c>null</c> if the underlay isn't in the cache. /// </summary> public async Task <string?> GetCacheFilenameAsync(SatelliteDefinition?definition, ProjectionOptions options) { await using var connection = new SqliteConnection(ConnectionString); await connection.OpenAsync(); var sql = "SELECT Filename FROM UnderlayCache WHERE Configuration=@Configuration"; if (definition != null) { sql += " AND Longitude=@Longitude"; } return(await connection.QueryFirstOrDefaultAsync <string>(sql, new { definition?.Longitude, Configuration = JsonConvert.SerializeObject(options) })); }
public async Task <Operation <IPage <TObject> > > GetAsync(string query = null, SortOptions sort = null, PageOptions page = null, FieldOptions fields = null, FilterOptions filter = null, ProjectionOptions projection = null) { _db.SetTypeInfo(typeof(TObject)); if (sort == null || sort == SortOptions.Empty) { sort = SortOptions.FromType <TObject>(x => x.Id); } if (page == null || page == PageOptions.Empty) { page = new PageOptions { Page = 1, PerPage = _options.CurrentValue.PerPageDefault } } ; var sql = _dialect.Build <TObject>(sort, fields, filter, projection); var data = (await _db.Current.QueryAsync <TObject>(PageBuilder.Page(_dialect, sql), new { page.Page, page.PerPage })).AsList(); var total = await _db.Current.ExecuteScalarAsync <long>(_dialect.Count(_descriptor, filter?.Fields)); var slice = new Page <TObject>(data, data.Count, page.Page - 1, page.PerPage, total); return(new Operation <IPage <TObject> >(slice)); }
public virtual async Task <IPage <Person> > GetAsync(string query = null, SortOptions sort = null, PageOptions page = null, FieldOptions fields = null, FilterOptions filter = null, ProjectionOptions projection = null) { var operation = await _repository.GetAsync(query, sort, page, fields, filter, projection); return(operation.Data); }
public Task <Operation <IStream <TObject> > > GetAsync(SegmentOptions segment, FieldOptions fields = null, FilterOptions filter = null, ProjectionOptions projection = null) { _db.SetTypeInfo(typeof(TObject)); throw new NotImplementedException("Segmentation not available."); }
/// <summary> /// Retrieves an underlay image from the cache. /// </summary> public async Task <Image <Rgba32>?> GetUnderlayAsync(SatelliteDefinition?definition, ProjectionOptions options) { var path = await _repository.GetCacheFilenameAsync(definition, options); if (path == null) { return(null); } var fullPath = Path.Combine(_cachePath, path); // Remove underlay registration from cache if it has been deleted from disk if (!File.Exists(fullPath)) { _logger.LogWarning("Cache file {path} not found; removing from cache registration", path); await _repository.ClearCacheEntryAsync(path); } try { if (definition == null) { _logger.LogInformation("Using cached underlay"); } else { _logger.LogInformation("{definition:l0} Using cached underlay", definition.DisplayName); } return(await Image.LoadAsync <Rgba32>(fullPath)); } catch (Exception e) { // Remove underlay registration from cache if there was an error reading it from disk _logger.LogWarning(e, "Cache file {path} unable to be read; removing from cache registration", path); await _repository.ClearCacheEntryAsync(path); } return(null); }
public static bool Any(this ProjectionOptions options, ProjectionOptions flag) { return 0 != (options & flag); }
public static string Select <T>(this ISqlDialect dialect, FieldOptions fields, ProjectionOptions projections) { return(Select(dialect, typeof(T), fields, projections)); }
public virtual async Task <Operation <IPage <Person> > > GetAsync(string query = null, SortOptions sort = null, PageOptions page = null, FieldOptions fields = null, FilterOptions filter = null, ProjectionOptions projection = null) { _db.SetTypeInfo(typeof(Person)); if (sort == SortOptions.Empty) { sort = DefaultSort; } // SELECT * FROM X WHERE Y ORDER BY Z... var sql = _dialect.Build <Person>(sort, fields, filter, projection); // FETCH OFFSET... var data = await _db.Current.QueryAsync <Person>(PageBuilder.Page(_dialect, sql), new { page.Page, page.PerPage }); // SELECT COUNT(1) WHERE ... var total = await _db.Current.ExecuteScalarAsync <long>(_dialect.Count <Person>(_descriptor, filter)); var slice = new Page <Person>(data, data.Count(), page.Page - 1, page.PerPage, total); return(new Operation <IPage <Person> >(slice)); }
public void Execute(IDictionary <string, StringValues> qs, ref QueryContext context) { qs.TryGetValue(_options.Value.ProjectionOperator, out var projections); ProjectionOptions options; if (projections.Count == 0) { options = ProjectionOptions.Empty; } else { options = new ProjectionOptions(); foreach (var projection in projections) { foreach (var value in projection.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { var v = value.Trim(); var attribute = new Projection { Field = v.ToUpperInvariant() }; options.Fields.Add(attribute); } } } if (!options.Validate(context.Type, _options.Value, out var errors)) { context.Errors.Add(new Error(ErrorEvents.ValidationFailed, ErrorStrings.ValidationFailed, HttpStatusCode.BadRequest, errors)); } else { if (options.Fields.Count > 0) { var members = TypeAccessor.Create(context.Type).GetMembers(); foreach (var field in options.Fields) { foreach (var member in members) { if (!field.Field.Equals(member.Name, StringComparison.OrdinalIgnoreCase)) { continue; } if (typeof(IEnumerable).IsAssignableFrom(member.Type)) { field.Type = ProjectionType.OneToMany; break; } if (member.Type.IsClass && member.Type != typeof(string)) { field.Type = ProjectionType.OneToOne; break; } field.Type = ProjectionType.Scalar; break; } } } context.Projections = options; } }
public virtual Task <Operation <IStream <Person> > > GetAsync(IEnumerable <long> ids, long startingAt = 0, int?count = null, FieldOptions fields = null, FilterOptions filter = null, ProjectionOptions projection = null) { _db.SetTypeInfo(typeof(Person)); throw new NotImplementedException("Streaming not available."); }
public BatchedFactory(int limit, ProjectionOptions options) : base(options) { if (limit < 1) throw new ArgumentOutOfRangeException("limit"); this.limit = limit; }