nightroman / Mdbc

MongoDB Cmdlets for PowerShell
Apache License 2.0
141 stars 16 forks source link

Some properties are missing for registered types #74

Closed codaamok closed 1 year ago

codaamok commented 1 year ago

Firstly, love this. Thank you. I am learning mongodb and being able to learn it with PowerShell helps me so much.

During my learning experience I uncovered Mdbc can't serialise all types, I must use Register-MdbcClassMap. Which is fine. As an example, I'm trying to run:

get-item .\Downloads\mongodb-windows-x86_64-6.0.3-signed.msi | Add-MdbcData

I needed to register all of the following types in order to add the data:

Register-MdbcClassMap -Type ([System.IO.DirectoryInfo])
Register-MdbcClassMap -Type ([System.Diagnostics.FileVersionInfo])
Register-MdbcClassMap -Type ([System.Management.Automation.ProviderInfo])
Register-MdbcClassMap -Type ([System.Management.Automation.PSDriveInfo])

After this, I was able to successfully add my System.IO.FileInfo object as data to my mongodb collection šŸŽ‰

When looking at the data in the collection, some properties are missing, for example see below screenshot. Is there anything I can do to ensure all properties from other types/objects are added? I'll likely be throwing in Pester data in collections once I get comfortable with how to use.

image

nightroman commented 1 year ago

Class mapping is the advanced C# driver topic (and I'm not exactly an expert). But in your particular case values might be not "missing" but actual nulls. Can you check on your side?

For example, this script

Set-StrictMode -Version 3

$r = Get-PSDrive C
$r | Format-List * | Out-String

$null -eq $r.MaximumSize
$null -eq $r.DisplayRoot

shows that your properties are nulls in my case.

codaamok commented 1 year ago

I'm mostly looking at the Name property more than anything.

PS C:\Users\WDAGUtilityAccount> $null -eq (get-item .\Downloads\mongodb-windows-x86_64-6.0.3-signed.msi).psdrive.name
False
PS C:\Users\WDAGUtilityAccount> $null -eq (get-psdrive 'c').name
False

Just seems like a regular string?

nightroman commented 1 year ago

Well, this is a question to the C# driver class map makers then :) I do not know why Name is not saved. Name only has get, maybe they do not consider such properties suitable for saving. Other saved properties have at least internal set (used ILSpy for getting this).

nightroman commented 1 year ago

I would not call this issue surprising though. We cannot expect than any type is suitable for mapping and that the default mapping is what we want.

nightroman commented 1 year ago

Also, keep in mind that mapping is designed for two way serialization, to BSON first and then recreating from BSON. A property with get only is "presumably calculated", so "there is no need to store it".

nightroman commented 1 year ago

If you still want to go this route, then you need a custom mapping, read the C# driver manuals.

e.g. this map

Register-MdbcClassMap -Type ([System.Management.Automation.PSDriveInfo]) -Init {
    $null = $_.MapProperty('Name')
    $null = $_.MapProperty('Root')
}

will result in Name and Root saved.

Here is some old-ish tutorial https://mongodb.github.io/mongo-csharp-driver/1.11/serialization/

codaamok commented 1 year ago

I appreciate your insight! Thank you šŸ˜„

nightroman commented 1 year ago

I think this might work for you:

Register-MdbcClassMap -Type ([System.Management.Automation.PSDriveInfo]) -Init {
    $_.AutoMap()
    $null = $_.MapProperty('Name')
}
nightroman commented 1 year ago

I will add this use case to tests, it's useful, thank you for the question.

nightroman commented 1 year ago

Here it is https://github.com/nightroman/Mdbc/blob/a367f5791ec4ee55ea30bf7dee0ca8cc1c707b1f/Tests/Classes.test.ps1#L346-L361