lib/CacheStores.ps1

function Open-TMCache {
    <#
    .SYNOPSIS
    Opens an existing CacheStore
     
    .DESCRIPTION
    This function opens a CacheStore by name in the current user profile.
     
    .PARAMETER Number
    The number to test
     
    .EXAMPLE
    Test-PrimeNumber -Number @(1, 5, 754, 436, 87546, 31)
     
    .EXAMPLE
    (1..100) | Test-PrimeNumber
     
    .OUTPUTS
    A boolean value indicating if the given number is a prime number
    #>


    [CmdletBinding()]      # Always add CmdletBinding to expose the common Cmdlet variables
    # [OutputType([LiteDB.LiteCollection])] # Add this if the function has an output
    param(        
        [Parameter(Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        [String]
        $Name,
        [Parameter(Mandatory = $False,
            Position = 1,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        [String]
        $Path = 'Default'
    )

    begin {
                
        $LdbcModule = Get-Module 'Ldbc' -ErrorAction 'SilentlyContinue'
        if (-not $LdbcModule) {
            Import-Module 'Ldbc'
        }
    
        ##
        ## Handle the Path definition
        ##

        if ($Path -eq 'Default') {
            $DatabaseFolderPath = Join-Path $userFilesRoot 'cache'
        }
        
        ## Check if it was a Fully Qualified Path
        elseif ([System.IO.Path]::IsPathRooted($Path)) {

            $DatabaseFolderPath = Join-Path $Path
            
        }
        
        ## Partial Path found, appending to the Cache directory from the Default lcoation
        else {
            $DatabaseFolderPath = Join-Path $userFilesRoot 'cache' $Path
        }

        ## Test the file path and create it if it doesn't exit
        Test-FolderPath -FolderPath $DatabaseFolderPath

        ## Check/Create the file path
        $DatabaseFilePath = Join-Path $DatabaseFolderPath 'tmcache.db'
        if (-Not (Test-Path -Path $DatabaseFilePath)) {
            New-Item -Path $DatabaseFilePath -Force
        }
    }

    process {
        
        ## Check to see if the Database is already open
        if (-not $Global:TMConsoleDB) {
            $Global:TMConsoleDB = New-LiteDatabase $DatabaseFilePath
        }
        
        Get-LiteCollection -CollectionName $Name -Database $Global:TMConsoleDB
        
    }

    end {
        # Cleanup resources
        # Will be executed only once per function call.
        # This block can be omitted
    }
}

function Get-TMCacheItem {
    <#
    .SYNOPSIS
    Creates a new CacheStore
     
    .DESCRIPTION
    This function creates a new CacheStore by name in the current user profile.
     
    
    .EXAMPLE
    Test-PrimeNumber -Number @(1, 5, 754, 436, 87546, 31)
     
    .EXAMPLE
    (1..100) | Test-PrimeNumber
     
    .OUTPUTS
    A boolean value indicating if the given number is a prime number
    #>


    [CmdletBinding()]      # Always add CmdletBinding to expose the common Cmdlet variables
    # [OutputType([Bool])] # Add this if the function has an output
    param(        
        
        [Parameter(Mandatory = $false)]
        [String]$Cache = 'Default', 

        [Parameter(Mandatory = $false,
            Position = 1,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        $Filter, 

        [Parameter(Mandatory = $false,
            Position = 1,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        $Id,
        
        [Parameter(Mandatory = $false,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        [Int32]$First,

        [Parameter(Mandatory = $false,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        [Int32]$Last,

        [Parameter(Mandatory = $false,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        [Switch]$SortAsc,

        [Parameter(Mandatory = $false,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        [Switch]$SortDesc,
        
        [Parameter(Mandatory = $false,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        [object]$OrderBy,
        
        [Parameter(Mandatory = $false,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        [object[]]$Select,

        [Parameter(Mandatory = $false,
            ValueFromPipeline = $true, 
            ValueFromPipelineByPropertyName = $true)]
        [Int32]$Skip


    )
    begin {
        
        $LdbcModule = Get-Module 'Ldbc' -ErrorAction 'SilentlyContinue'
        if (-not $LdbcModule) {
            Import-Module 'Ldbc'
        }

        $DBPath = Join-Path $global:TMCacheFilePath 'Default.db'

    }

    process {
        
        ## Create a Splat hashtable
        $QuerySplat = @{}
        $QuerySplat.As = 'PS'
        
        ##
        ## Handle Filtering/Selecting the records
        ##

        if ($Filter) {
            $QuerySplat.Where = $Filter
        }
        
        ## Filter by ID
        elseif ($Id) {
            $QuerySplat.Where = '_id = {$oid: "' + $Id + '"}'
        }
        
        ##
        ## Handle other Parameters
        ##

        if ($First) {
            $QuerySplat.First = $First
        }
        if ($Last) {
            $QuerySplat.Last = $Last
        }
        if ($Skip) {
            $QuerySplat.Skip = $Skip
        }
        if ($SortAsc) {
            $QuerySplat.Order = 1
        }
        if ($SortDesc) {
            $QuerySplat.Order = -1
        }
        if ($OrderBy) {
            $QuerySplat.OrderBy = $OrderBy
        }
        if ($Select) {
            
            ## Use JSON Class defined result
            if (($Select[0].Substring(0, 1) -eq '{') -and ($Select[0].Substring($Select[0].Length - 1, 1) -eq '}')) {
                $QuerySplat.Select    
            }

            ## Otherwise it's a list of strings, concatenate to the proper Select syntax
            else {
                $QuerySplat.Select = '{' + ($Select -join ', ') + '}'
            }
        }
        
        ## Rescope some variables so they are available inside the use-litedb transactin scriptblock
        $CacheName = ($Cache -replace ' ', '_' -replace '-', '_').ToLower()
        $Global:CollectionName = $CacheName
        $Global:QuerySplat = $QuerySplat

        Use-LiteDatabase $DBPath {
            
            ## Get the Collection the data is in
            $Collection = Get-LiteCollection -CollectionName $Global:CollectionName
            Get-LiteData -Collection $Collection @Global:QuerySplat
        }
    }
    end {

        Remove-Variable CollectionName -Scope Global
        Remove-Variable QuerySplat -Scope Global
    }
}
function Set-TMCacheItem {
    <#
    .SYNOPSIS
    Creates a new CacheStore
     
    .DESCRIPTION
    This function creates a new CacheStore by name in the current user profile.
     
    
    .EXAMPLE
    Test-PrimeNumber -Number @(1, 5, 754, 436, 87546, 31)
     
    .EXAMPLE
    (1..100) | Test-PrimeNumber
     
    .OUTPUTS
    A boolean value indicating if the given number is a prime number
    #>


    [CmdletBinding()]      # Always add CmdletBinding to expose the common Cmdlet variables
    # [OutputType([Bool])] # Add this if the function has an output
    param(        
        
        [Parameter(Mandatory = $true,
            ValueFromPipeline = $true)]
        [object]$InputObject,

        [Parameter(Mandatory = $false)]
        [String]$Cache = 'Default', 
        
        [Parameter(Mandatory = $false)]
        [AllowNull()]
        [String]$IdProperty = '_id'

    )

    begin {
        try {

            ## Ensure that the LDBC module is loaded
            $LdbcModule = Get-Module 'Ldbc' -ErrorAction 'SilentlyContinue'
            if (-not $LdbcModule) {
                Import-Module 'Ldbc'
            }
            
            $CacheName = ($Cache -replace ' ', '_' -replace '-', '_').ToLower()
            
            ## Open a connection to the DB and Collection
            $DBPath = Join-Path $global:TMCacheFilePath 'Default.db'
            $DB = New-LiteDatabase -DB $DBPath
            $Collection = Get-LiteCollection -Database $DB -CollectionName $CacheName
            
            ## Ensure that the ID Property is indexed
            $Collection.EnsureIndex($IdProperty)
        }
        catch {
            throw $_
        }
        
    }
    process {

        ## If the InputObject property has a field with the IdProperty supplied
        if ($InputObject.PSObject.Properties.name -contains $IdProperty) {
            
            ## Get the Current Data
            # $Where = "$." + $IdProperty + " = '" + $InputObject.$IdProperty + "'"
            # $CurrentData = Get-LiteData -Collection $Collection -Where $Where
            $CurrentData = Get-LiteData -Collection $Collection
            
            ## Set the InputObject _id property with the Current Data ID to replace it
            if ($CurrentData) {
                
                ## Set the LiteDB _id field with the ID property provided
                Add-Member -InputObject $InputObject -NotePropertyName '_id' -NotePropertyValue $CurrentData._id -Force
                $InputObject = $CurrentData
            }
        }
        
        ## Set the Data in the Cache
        $InputObject | Set-LiteData -Collection $Collection -Add

    }

    end {
        
        ## Close the Handle to the Database
        $DB.Dispose()
    }
}
function Remove-TMCacheItem {
    <#
    .SYNOPSIS
    Creates a new CacheStore
     
    .DESCRIPTION
    This function creates a new CacheStore by name in the current user profile.
     
    
    .EXAMPLE
    Test-PrimeNumber -Number @(1, 5, 754, 436, 87546, 31)
     
    .EXAMPLE
    (1..100) | Test-PrimeNumber
     
    .OUTPUTS
    A boolean value indicating if the given number is a prime number
    #>


    [CmdletBinding()]      # Always add CmdletBinding to expose the common Cmdlet variables
    # [OutputType([Bool])] # Add this if the function has an output
    param(        
        
        [Parameter(Mandatory = $false,
            ValueFromPipeline = $true)]
        [object]$InputObject,

        [Parameter(Mandatory = $false)]
        [String]$Cache = 'Default', 
        
        [Parameter(Mandatory = $false)]
        [AllowNull()]
        [String]$IdProperty = '_id',
        
        [Parameter(Mandatory = $false)]
        [AllowNull()]
        [String]$Filter

    )

    begin {
        try {

            ## Ensure that the LDBC module is loaded
            $LdbcModule = Get-Module 'Ldbc' -ErrorAction 'SilentlyContinue'
            if (-not $LdbcModule) {
                Import-Module 'Ldbc'
            }
            
            $CacheName = ($Cache -replace ' ', '_' -replace '-', '_').ToLower()
            
            ## Open a connection to the DB and Collection
            $DBPath = Join-Path $global:TMCacheFilePath 'Default.db'
            $DB = New-LiteDatabase -DB $DBPath
            $Collection = Get-LiteCollection -Database $DB -CollectionName $CacheName
            
            ## Ensure that the ID Property is indexed
            # $Collection.EnsureIndex($IdProperty)
        }
        catch {
            throw $_
        }
        
    }
    process {

        ## If the InputObject property has a field with the IdProperty supplied
        if ($Filter) {
            ## Get the Current Data
            Remove-LiteData -Collection $Collection -Where $Filter
        }
        
        else {
            if ($InputObject.PSObject.Properties.name -contains $IdProperty) {
                
                ## Get the Current Data
                $Where = '$.' + $IdProperty + ' = "' + $InputObject.$IdProperty + '"'
                $CurrentResults = Get-LiteData -Collection $Collection -Where $Where

                foreach ($Result in $CurrentResults) {
                    Remove-LiteData -InputObject $Result -Collection $Collection
                }
            }
        }
    }

    end {
        
        ## Close the Handle to the Database
        $DB.Dispose()
    }
}
function Add-TMCacheIndex {
    <#
    .SYNOPSIS
    Creates a new CacheStore
     
    .DESCRIPTION
    This function creates a new CacheStore by name in the current user profile.
     
    
    .EXAMPLE
    Test-PrimeNumber -Number @(1, 5, 754, 436, 87546, 31)
     
    .EXAMPLE
    (1..100) | Test-PrimeNumber
     
    .OUTPUTS
    A boolean value indicating if the given number is a prime number
    #>


    [CmdletBinding()]      # Always add CmdletBinding to expose the common Cmdlet variables
    # [OutputType([Bool])] # Add this if the function has an output
    param(        
        
        [Parameter(Mandatory = $true,
            ValueFromPipeline = $true)]
        [object[]]$IndexProperty,

        [Parameter(Mandatory = $false)]
        [String]$Cache = 'Default'
        

    )

    begin {
        
        ## Ensure that the LDBC module is loaded
        $LdbcModule = Get-Module 'Ldbc' -ErrorAction 'SilentlyContinue'
        if (-not $LdbcModule) {
            Import-Module 'Ldbc'
        }
        
        ## Open a connection to the DB and Collection
        $DBPath = Join-Path $global:TMCacheFilePath 'Default.db'
        $DB = New-LiteDatabase -DB $DBPath
        $Collection = Get-LiteCollection -Database $DB -CollectionName $Cache
        
    }
    process {

        ## Add each Index Property
        foreach ($PropertyName in $IndexProperty) {
            
            ## Ensure that the ID Property is indexed
            $Collection.EnsureIndex("idx_$($PropertyName)", "LOWER($.$($PropertyName))", $true)
        }
    }

    end {
        
        ## Close the Handle to the Database
        $DB.Dispose()
    }
}