/// <summary> /// Appends a call to <c>JSON_VALUE</c> from the current column and JSON path, e.g. <c>JSON_VALUE(T0."MyJson", '$.my.value')</c>, to the attribute buffer. /// </summary> /// <param name="attribute">The current attribute.</param> /// <returns>A new attribute containing the appended buffer.</returns> public static IProjectionAttribute Json(this IProjectionAttribute attribute) { IJsonMetadata json = ProjectionHelper.GetJsonMetadata(attribute); IProjectionMetadata metadata = attribute.Metadata; IProjectionMetadata rootMetadata = json.MemberOf.Identity.GetMetadata <IProjectionMetadata>(); attribute = attribute.Append("JSON_VALUE("); try { attribute = attribute.With(metadata: rootMetadata).Col(); } catch (ProjectionException ex) { throw ProjectionException.FromProjection(attribute, "JSON value requires a column to read from.", innerException: ex); } attribute = attribute.Append(","); attribute = attribute.With(metadata: metadata).JsonPath(); attribute = attribute.Append(")"); return(attribute); }
/// <summary> /// Appends a table-valued parameter from the current values, e.g. <c>@TP0</c>, to the projection buffer. /// </summary> /// <param name="projection">The current projection.</param> /// <returns>A new attribute containing the appended buffer.</returns> public static IProjectionAttribute TvpName(this IProjection projection) { if (projection.Source == null) { throw ProjectionException.ValueNotFound(projection); } else if (!projection.Attributes.Any()) { throw ProjectionException.FromProjection(projection, "No attributes found."); } IProjectionMetadata metadata = TvpHelper.GetPreferredTvpMetadata(projection); IField source = new Relation(projection.Source, metadata.Identity.Name).Scalar(); RelationIdentity identity = new RelationIdentity(metadata.Identity.Schema, projection.Attributes.Select(a => a.Metadata.Identity)); IBindingParameterContract contract = TvpCache.GetParameterContract(identity); string paramName = projection.Context.Lookup.Custom("TP", projection.Identity, field: source); string dialectName = projection.Context.Domain.Dialect.Parameter(paramName); return(projection.Attr().Append(dialectName).Append(new Parameter(paramName, source, contract))); }
private IEnumerable <IProjectionAttribute> CreateDefaultAttributes(IProjectionMetadata metadata) { IEnumerable <IProjectionMetadata> attributes = this.SelectAttributes(metadata); IEnumerable <Func <IField> > fields = attributes.Select(_ => (Func <IField>)null); IField source = this.Source; if (source != null) { Lazy <ITuple> tuple = new Lazy <ITuple>(() => { Relation relation = new Relation(source, attributes.Select(m => m.Identity)); return(relation.Row()); }); fields = attributes.Select((_, i) => new Func <IField>(() => tuple.Value[i])); } foreach (var(m, f) in attributes.Zip(fields)) { yield return(new ProjectionAttribute(this).With(metadata: m, field: f)); } }
internal static ProjectionException JsonNotFound(IProjectionMetadata metadata) => new ProjectionException($"No JSON information found for {metadata.Identity}.");
internal static ProjectionException ColumnNotFound(IProjectionMetadata metadata) => new ProjectionException($"No column information found for {metadata.Identity}.");
internal static ProjectionException TableNotFound(IProjectionMetadata metadata) => new ProjectionException($"No table information found for {metadata.Identity}.");
internal static ProjectionException AttributesNotFound(IProjectionMetadata metadata) => new ProjectionException($"No attributes found for {metadata.Identity}.");
internal static ProjectionException InvalidLambda(IProjectionMetadata metadata, LambdaExpression expression) => new ProjectionException($"Cannot navigate from {metadata.Identity}: Expression '{expression}' is not valid.");
public static bool HasAnyFlag(this IProjectionMetadata metadata, ReferenceMetadataFlags flag) => (metadata.Relation != null && metadata.Reference.HasAnyFlag(flag));
public static bool HasAnyFlag(this IProjectionMetadata metadata, ProjectionMetadataFlags flag) => (metadata.Flags & flag) != ProjectionMetadataFlags.None;
public static IJsonMetadata GetJsonMetadata(IProjectionMetadata metadata) => metadata.Identity.Lookup <IJsonMetadata>() ?? throw ProjectionException.JsonNotFound(metadata);
public new IProjection <TModel> With(IProjectionMetadata metadata = null, IEnumerable <IProjectionAttribute> attributes = null, IField field = null, IProjectionOptions options = null) => new Projection <TModel>(base.With(metadata, attributes, field, options));
internal Projection(IProjectionIdentity identity, IProcContext context, IProjectionMetadata metadata) : base(identity, context, metadata) { }
public new IProjection <TModel> With(IProjectionMetadata metadata = null, IProjectionData data = null, IEnumerable <IProjectionAttribute> header = null, IProjectionOptions options = null) => new Projection <TModel>(base.With(metadata, data, header, options));
public Projection(ProjectionIdentity identity, IProcContext context, IProjectionMetadata metadata) : base(identity, context, metadata) { }
internal static ProjectionException PropertyNotFound(IProjectionMetadata metadata) => new ProjectionException($"No property information found for {metadata.Identity}.");
public ProjectionAttribute(ProjectionIdentity identity, IProcContext context, IProjectionMetadata metadata, IProjectionData data) { this.Identity = identity ?? throw ProjectionException.ArgumentNull(nameof(identity), metadata); this.Context = context ?? throw ProjectionException.ArgumentNull(nameof(context), metadata); this.Metadata = metadata ?? throw ProjectionException.ArgumentNull(nameof(metadata), metadata); this.Data = data; this.Content = SqlContent.Empty; }
public static ITableMetadata GetTableMetadata(IProjectionMetadata metadata) => GetPreferredTableMetadata(metadata)?.Table;
public static bool HasFlag(this IProjectionMetadata metadata, ProjectionMetadataFlags flag) => (metadata.Flags & flag) == flag;
private ProcFactory CreateProcFactory(PageDescriptor descriptor, ProcArgs args) { IDomainOptions options = this.Options(descriptor.DomainType); PageDescriptor[] template = this.GetTemplateHierarchy(descriptor).Reverse().ToArray(); PageConstructor[] factories = template.Select(t => this.CreatePageConstructor(t.PageType)).Concat(new PageConstructor[1]).ToArray(); IProjectionMetadata resultMetadata = this.GetMetadataForResult(descriptor, args, options); IProjectionMetadata modelMetadata = this.GetMetadataForModel(descriptor, args, options); ISchema resultSchema = resultMetadata.Identity.Schema; ISchema modelSchema = modelMetadata.Identity.Schema; IProcLocator locator = descriptor.Locator; Type originType = descriptor.OriginType; IProcResult procFactory(object model) { ProcContext context = this.CreateContext(descriptor); ProjectionIdentity modelIdentity = new ProjectionIdentity(new Model(modelSchema, model)); ProjectionIdentity resultIdentity = new ProjectionIdentity(resultSchema); IProjection modelProjection = new Projection(modelIdentity, context, modelMetadata); IProjection resultProjection = new Projection(resultIdentity, context, resultMetadata); PageExecutionContext[] execution = template.Select(t => new PageExecutionContext() { Page = t }).ToArray(); execution[0].Buffer = new ProcBuffer(); for (int i = 0; i < execution.Length; i++) { PageConstructor nextFactory = factories[i + 1]; if (nextFactory != null) { PageExecutionContext nextContext = execution[i + 1]; execution[i].Body = () => { ISqlPage bodyPage = nextFactory(modelProjection, resultProjection); context.Stack.Push(nextContext); bodyPage.Execute(); context.Stack.Pop(); }; } } ISqlPage page = factories[0](modelProjection, resultProjection); context.Stack.Push(execution[0]); page.Execute(); return(new ProcResult() { Buffer = context.Execution.Buffer, Domain = options, }); } return(procFactory); }
/// <summary> /// Navigates the current projection to a selected target. /// </summary> /// <param name="projection">The current projection.</param> /// <param name="expression">Expression selecting a projection target.</param> /// <returns>A new projection from the selected target.</returns> public static IProjection <TProperty> For <TModel, TProperty>(this IProjection <TModel> projection, Expression <Func <TModel, TProperty> > expression) { IProjectionMetadata metadata = ProjectionHelper.GetMetadataFromRelativeLambda(projection, expression); return(projection.With(metadata).Cast <TProperty>()); }
internal static ProjectionException ArgumentNull(string argumentName, IProjectionMetadata metadata) => InvalidProjection(metadata, message: $"Argument '{argumentName}' cannot be null.");
public static bool HasAnyFlag(this IProjectionMetadata metadata, TableMetadataFlags flag) => (metadata.Table != null && metadata.Table.HasAnyFlag(flag));