Skip to content

Commit

Permalink
Improve errors on getting stream
Browse files Browse the repository at this point in the history
  • Loading branch information
iJungleboy committed Sep 17, 2021
1 parent 78fe605 commit 62cd491
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 5 deletions.
2 changes: 1 addition & 1 deletion ToSic.Eav.DataSources/DataSources/App_OutBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private void CreateAppOutWithAllStreams()
() => new CacheInfoAppAndMore("AppTypeStream" + AppRootCacheKey.AppCacheKey(this), appState, $"Name={typeName}&Drafts={showDrafts}"),
this,
typeName,
() => BuildTypeStream(upstreamDataSource, typeName)[Constants.DefaultStreamName].List.ToImmutableArray(),
() => BuildTypeStream(upstreamDataSource, typeName).List /*[Constants.DefaultStreamName].List*/.ToImmutableArray(),
true);
_out.Add(typeName, deferredStream);
}
Expand Down
35 changes: 32 additions & 3 deletions ToSic.Eav.DataSources/DataSources/DataSourceBase_Connections.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using ToSic.Eav.Data;
using ToSic.Eav.Documentation;

Expand All @@ -19,10 +20,38 @@ public abstract partial class DataSourceBase
public virtual IDictionary<string, IDataStream> Out { get; protected internal set; } = new StreamDictionary();

/// <inheritdoc />
public IDataStream this[string outName] => Out[outName];
public IDataStream this[string outName] => GetStream(outName);

/// <inheritdoc />
public IEnumerable<IEntity> List => Out[Constants.DefaultStreamName].List;
public IDataStream GetStream(string name = null, string noParameterOrder = Parameters.Protector, bool nullIfNotFound = false, bool emptyIfNotFound = false)
{
Parameters.ProtectAgainstMissingParameterNames(noParameterOrder, nameof(GetStream), $"{nameof(nullIfNotFound)}");

// Check if streamName was not provided
if (string.IsNullOrEmpty(name)) name = Constants.DefaultStreamName;

// Simple case - just get it
if (Out.ContainsKey(name)) return Out[name];

if (nullIfNotFound && emptyIfNotFound)
throw new ArgumentException($"You cannot set both {nameof(nullIfNotFound)} and {nameof(emptyIfNotFound)} to true");

// If null is preferred to an error, return this
if (nullIfNotFound) return null;

// If empty is preferred to an error, return this
if (emptyIfNotFound) return new DataStream(this, name, () => new List<IEntity>());

// Not found and no rule to handle it, throw error
throw new KeyNotFoundException(
$"Can't find Stream with the name '{name}'. This could be a typo. Otherwise we recommend that you use either " +
$"'{nameof(nullIfNotFound)}: true' (for null-checks or ?? chaining) " +
$"or '{nameof(emptyIfNotFound)}: true' (for situations where you just want to add LINQ statements"
);
}

/// <inheritdoc />
public IEnumerable<IEntity> List => GetStream().List; // Out[Constants.DefaultStreamName].List;


#region various Attach-In commands
Expand Down
15 changes: 15 additions & 0 deletions ToSic.Eav.DataSources/Interfaces/IDataSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ public interface IDataSource: IDataPartShared, IAppIdentity, ICacheInfo, ICanPur
/// <exception cref="NullReferenceException">if the stream does not exist</exception>
IDataStream this[string outName] { get; }

/// <summary>
/// Gets the Out-Stream with specified Name and allowing some error handling if not found.
/// </summary>
/// <param name="name">The desired stream name. If empty, will default to the default stream.</param>
/// <param name="noParameterOrder">see [](xref:NetCode.Conventions.NamedParameters)</param>
/// <param name="nullIfNotFound">In case the stream <see cref="name"/> isn't found, will return null. Ideal for chaining with ??</param>
/// <param name="emptyIfNotFound">In case the stream <see cref="name"/> isn't found, will return an empty stream. Ideal for using LINQ directly.</param>
/// <returns>an <see cref="IDataStream"/> of the desired name</returns>
/// <exception cref="NullReferenceException">if the stream does not exist and <see cref="nullIfNotFound"/> is false</exception>
/// <remarks>
/// 1. Added in 2sxc 12.05
/// 1. for more in-depth checking if a stream exists, you can access the <see cref="Out"/> which is an IDictionary
/// </remarks>
IDataStream GetStream(string name = null, string noParameterOrder = Parameters.Protector, bool nullIfNotFound = false, bool emptyIfNotFound = false);

/// <summary>
/// The items in the data-source - to be exact, the ones in the Default stream.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion ToSic.Eav.DataSources/Queries/QueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public QueryDefinition GetQueryDefinition(int appId, int queryEntityId)
{
var app = _appStates.Identity(null, appId);
var source = _dataSourceFactory.GetPublishing(app);
var appEntities = source[Constants.DefaultStreamName].List;
var appEntities = source.List; // [Constants.DefaultStreamName].List;

// use findRepo, as it uses the cache, which gives the list of all items
var dataQuery = appEntities.FindRepoId(queryEntityId);
Expand Down

0 comments on commit 62cd491

Please sign in to comment.