bin/projects/dbatools/dbatools/Commands/SelectDbaObjectCommand.cs
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Management.Automation; using System.Text; using System.Threading.Tasks; using Sqlcollaborative.Dbatools.Parameter; namespace Sqlcollaborative.Dbatools.Commands { /// <summary> /// Implements the Select-DbaObject command /// </summary> [Cmdlet("Select", "DbaObject", DefaultParameterSetName = "DefaultParameter", RemotingCapability = RemotingCapability.None)] public class SelectDbaObjectCommand : PSCmdlet { #region Parameters /// <summary> /// The actual input object that is being processed /// </summary> [Parameter(ValueFromPipeline = true)] public PSObject InputObject; /// <summary> /// The properties to select. Supports fancy DSL /// </summary> [Parameter(ParameterSetName = "DefaultParameter", Position = 0)] [Parameter(ParameterSetName = "SkipLastParameter", Position = 0)] public DbaSelectParameter[] Property = new DbaSelectParameter[0]; /// <summary> /// Properties to skip /// </summary> [Parameter(ParameterSetName = "DefaultParameter")] [Parameter(ParameterSetName = "SkipLastParameter")] public string[] ExcludeProperty = new string[0]; /// <summary> /// A property to expand. /// </summary> [Parameter(ParameterSetName = "DefaultParameter")] [Parameter(ParameterSetName = "SkipLastParameter")] public string ExpandProperty; /// <summary> /// Whether to exclude duplicates /// </summary> [Parameter()] public SwitchParameter Unique; /// <summary> /// The last number of items to pick /// </summary> [Parameter(ParameterSetName = "DefaultParameter")] [ValidateRange(0, 2147483647)] public int Last; /// <summary> /// Pick the first n items. /// </summary> [Parameter(ParameterSetName = "DefaultParameter")] [ValidateRange(0, 2147483647)] public int First; /// <summary> /// Skip n items before picking items /// </summary> [Parameter(ParameterSetName = "DefaultParameter")] [ValidateRange(0, 2147483647)] public int Skip; /// <summary> /// Skip the last n items /// </summary> [Parameter(ParameterSetName = "SkipLastParameter")] [ValidateRange(0, 2147483647)] public int SkipLast; /// <summary> /// /// </summary> [Parameter(ParameterSetName = "IndexParameter")] [Parameter(ParameterSetName = "DefaultParameter")] public SwitchParameter Wait; /// <summary> /// /// </summary> [Parameter(ParameterSetName = "IndexParameter")] [ValidateRange(0, 2147483647)] public int[] Index; /// <summary> /// THe properties to display by default /// </summary> [Parameter()] public string[] ShowProperty = new string[0]; /// <summary> /// The properties to NOT display by default /// </summary> [Parameter()] public string[] ShowExcludeProperty = new string[0]; /// <summary> /// The typename to assign to the psobject /// </summary> [Parameter()] public string TypeName; /// <summary> /// Keep the original input object, just add to it. /// </summary> [Parameter()] public SwitchParameter KeepInputObject; #endregion Parameters #region Private Fields /// <summary> /// List of properties to NOT clone into the hashtable used against Select-Object /// </summary> private string[] _NonclonedProperties = new string[] { "Property", "ShowProperty", "ShowExcludeProperty", "TypeName", "KeepInputObject" }; /// <summary> /// Whether some adjustments to the object need to be done or whether the Select-Object output can be simply passed through. /// </summary> private bool _NoAdjustment = true; /// <summary> /// The set controlling what properties will be shown by default /// </summary> private PSMemberInfo[] _DisplayPropertySet; /// <summary> /// THe pipeline that is wrapped around Select-Object /// </summary> private SteppablePipeline _Pipeline; #endregion Private Fields #region Command Implementation /// <summary> /// Implements the begin action of the command /// </summary> protected override void BeginProcessing() { object outBuffer; if (MyInvocation.BoundParameters.TryGetValue("OutBuffer", out outBuffer)) { MyInvocation.BoundParameters["OutBuffer"] = 1; } Hashtable clonedBoundParameters = new Hashtable(); foreach (string key in MyInvocation.BoundParameters.Keys) if (!_NonclonedProperties.Contains(key)) clonedBoundParameters[key] = MyInvocation.BoundParameters[key]; if (MyInvocation.BoundParameters.ContainsKey("Property")) clonedBoundParameters["Property"] = Property.Select(o => o.Value).AsEnumerable().ToArray(); if ((ShowExcludeProperty.Length > 0) || (ShowProperty.Length > 0) || (!String.IsNullOrEmpty(TypeName)) || (KeepInputObject.ToBool())) _NoAdjustment = false; if (ShowProperty.Length > 0) _DisplayPropertySet = new PSMemberInfo[] { new PSPropertySet("DefaultDisplayPropertySet", ShowProperty) }; // Set the list of parameters to a variable in the caller scope, so it can be splatted this.SessionState.PSVariable.Set("__PSFramework_SelectParam", clonedBoundParameters); ScriptBlock scriptCommand = ScriptBlock.Create("Select-Object @__PSFramework_SelectParam"); _Pipeline = scriptCommand.GetSteppablePipeline(MyInvocation.CommandOrigin); if (_NoAdjustment) _Pipeline.Begin(this); else _Pipeline.Begin(true); } /// <summary> /// Implements the process action of the command /// </summary> protected override void ProcessRecord() { if (_NoAdjustment) _Pipeline.Process(InputObject); else { PSObject item = PSObject.AsPSObject(_Pipeline.Process(InputObject).GetValue(0)); if (KeepInputObject.ToBool()) { PSObject tempItem = item; item = InputObject; foreach (PSPropertyInfo info in tempItem.Properties.Where(o => !item.Properties.Select(n => n.Name).Contains(o.Name))) item.Properties.Add(info); } if (ShowProperty.Length > 0) item.Members.Add(new PSMemberSet("PSStandardMembers", _DisplayPropertySet)); else if (ShowExcludeProperty.Length > 0) item.Members.Add(new PSMemberSet("PSStandardMembers", new PSMemberInfo[] { new PSPropertySet("DefaultDisplayPropertySet", item.Properties.Select(o => o.Name).Where(o => !ShowExcludeProperty.Contains(o))) })); if (!String.IsNullOrEmpty(TypeName)) item.TypeNames.Insert(0, TypeName); WriteObject(item); } } /// <summary> /// Implements the end action of the command /// </summary> protected override void EndProcessing() { _Pipeline.End(); } #endregion Command Implementation } } |