Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert ZService to functions #93

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
90 changes: 90 additions & 0 deletions ZLocation.Tests/ZLocation.Service.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
Describe 'ZLocation.Service' {
Import-Module $PSScriptRoot\..\ZLocation\ZLocation.Service.psd1 -Force
. "$PSScriptRoot/_mocks.ps1"

Context 'Testing database init' {
InModuleScope ZLocation.Service {
$dbpath = Get-ZLocationDatabaseFilePath
$testdbpattern = '*z-location-tests.db'
if ($dbpath -notlike $testdbpattern) {throw 'Not using test database, aborting tests'}
if (-not (Test-ZLocationDBUnlocked)) {throw 'Database is locked, aborting tests'}

# It 'Is referring to test DB' {
# $dbpath | Should -BeLike $testdbpattern
# }

It 'Initializes a database' {
if (Test-Path ($dbpath)) {Remove-Item $dbpath}

Initialize-ZLocationDB
Assert-MockCalled Get-ZLocationDatabaseFilePath
Test-Path $dbpath | Should -Be $true
}
}
}

Context 'Testing database functionality' {
InModuleScope ZLocation.Service {
$dbpath = Get-ZLocationDatabaseFilePath
$testdbpattern = '*z-location-tests.db'
if ($dbpath -notlike $testdbpattern) {throw 'Not using test database, aborting tests'}
if (-not (Test-ZLocationDBUnlocked)) {throw 'Database is locked, aborting tests'}

BeforeEach {
if (Test-Path $dbpath) {Remove-Item $dbpath}
Initialize-ZLocationDB
}

$path = [guid]::NewGuid().Guid

It 'Adds and retrieves a location' {
Update-ZDBLocation -Path $path
Get-ZDBLocation | Should -HaveCount 1
$l = [Location]::new()
$l.path = $path
$l.weight = 1
Get-ZDBLocation | Select-Object -First 1 | ConvertTo-Json | Should -Be ($l | ConvertTo-Json)
}

It 'Adds and removes a location' {
Update-ZDBLocation -Path $path
Remove-ZDBLocation $path
Get-ZDBLocation | Should -BeNullOrEmpty
}
}
}

# Context "Malformed DB entries" {
# try {
# # Connect to the database and add some malformed entries
# Add-Type -Path $PSScriptRoot\..\ZLocation\LiteDB\LiteDB.dll
# $connectionString = "Filename=$($testDb); Mode=Shared"
# $db = [LiteDB.LiteDatabase]::new($connectionString)
# $collection = $db.GetCollection('Location')
# $oidquery = [LiteDB.Query]::Where('_id',{$args -like '{"$oid":"*"}'})

# # Create and insert a malformed location
# $bsondocument = [LiteDB.BsonDocument]::new()
# $bsondocument['weight'] = 1234
# $collection.Insert($bsondocument)

# It "confirms malformed entries inserted" {
# # This actually tests the query more than anything.
# $malformedEntries = (,$collection.Find($oidquery))
# $malformedEntries | Should -HaveCount 1
# }

# It "can remove malformed location entries" {
# # Ensure nothing else can be connecting to $db to placate AppVeyor.
# $db.Dispose()
# Get-ZDBLocation
# $db = [LiteDB.LiteDatabase]::new($connectionString)
# $collection = $db.GetCollection('Location')
# $malformedEntries = $collection.Find($oidquery)
# $malformedEntries | Should -HaveCount 0
# }
# } finally {
# $db.Dispose()
# }
# }
}
2 changes: 1 addition & 1 deletion ZLocation/ZLocation.Service.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ GUID = '3d256bab-55d1-459c-8673-1d9d7ca8554a'
# Assembly must be loaded first or else powershell class will fail to compile
RequiredAssemblies = @("$PSScriptRoot/LiteDB/LiteDB.dll")
RootModule = 'ZLocation.Service.psm1'
FunctionsToExport = @('Get-ZService')
FunctionsToExport = @('Get-ZDBLocation','Update-ZDBLocation','Remove-ZDBLocation')
CmdletsToExport = @()
VariablesToExport = @()
AliasesToExport = @()
Expand Down
100 changes: 61 additions & 39 deletions ZLocation/ZLocation.Service.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ Set-StrictMode -Version Latest

Import-Module -Prefix DB (Join-Path $PSScriptRoot 'ZLocation.LiteDB.psd1')

class Service {
[Collections.Generic.IEnumerable[Location]] Get() {
# Get the locations in the database and their weights as [Location]s
function Get-ZDBLocation {
return (dboperation {
# Return an enumerator of all location entries
try {
Expand All @@ -28,34 +28,47 @@ class Service {
}
}
})
}
[void] Add([string]$path, [double]$weight) {
dboperation {
$l = DBGetById $collection $path ([Location])
if($l) {
$l.weight += $weight
DBUpdate $collection $l
} else {
$l = [Location]::new()
$l.path = $path
$l.weight = $weight
DBInsert $collection $l
}
}

# Increase the weight of a location in the database, adding it if not present.
function Update-ZDBLocation {
param (
# The location to update or add
[Parameter(Mandatory=$true)] [string]$Path,
# The amount to increase the path's weight by
[double]$Weight = 1.0
)
dboperation {
$l = DBGetById $collection $path ([Location])
if($l) {
$l.weight += $weight
DBUpdate $collection $l
} else {
$l = [Location]::new()
$l.path = $path
$l.weight = $weight
DBInsert $collection $l
}
}
[void] Remove([string]$path) {
dboperation {
# Use DB's internal column name, not mapped name
DBDelete $collection ([LiteDB.Query]::EQ('_id', [LiteDB.BSONValue]::new($path)))
}
}

# Remove a location from the database
function Remove-ZDBLocation {
param (
# The location to remove from the database
[Parameter(Mandatory=$true)] [string]$Path
)
dboperation {
# Use DB's internal column name, not mapped name
DBDelete $collection ([LiteDB.Query]::EQ('_id', [LiteDB.BSONValue]::new($path)))
}
}

class Location {
[LiteDB.BsonId()]
[string] $path;
[string] $Path;

[double] $weight;
[double] $Weight;
}

function Get-ZLocationDatabaseFilePath
Expand Down Expand Up @@ -105,26 +118,35 @@ function dboperation {
}
}

$dbExists = Test-Path (Get-ZLocationDatabaseFilePath)
$legacyBackupPath = Get-ZLocationLegacyBackupFilePath
$legacyBackupExists = ($legacyBackupPath -ne $null) -and (Test-Path $legacyBackupPath)

# Create empty db, collection, and index if it doesn't exist
dboperation {
$collection.EnsureIndex('path')
function Test-ZLocationDBUnlocked {
try {
[IO.File]::OpenWrite((Get-ZLocationDatabaseFilePath)).close()
$true
} catch {
$false
}
}

$service = [Service]::new()
function Initialize-ZLocationDB {
$dbExists = Test-Path (Get-ZLocationDatabaseFilePath)
$legacyBackupPath = Get-ZLocationLegacyBackupFilePath
$legacyBackupExists = ($null -ne $legacyBackupPath) -and (Test-Path $legacyBackupPath)

# Migrate legacy backup into database if appropriate
if((-not $dbExists) -and $legacyBackupExists) {
Write-Warning "ZLocation changed storage from $legacyBackupPath to $(Get-ZLocationDatabaseFilePath), feel free to remove the old txt file"
Get-Content $legacyBackupPath | Where-Object { $_ -ne $null } | ForEach-Object {
$split = $_ -split "`t"
$service.add($split[0], $split[1])
if (-not($dbExists)) {
# Create empty db, collection, and index if it doesn't exist
dboperation {
$collection.EnsureIndex('path')
}

# Migrate legacy backup into database if appropriate
if ($legacyBackupExists) {
Write-Warning "ZLocation changed storage from $legacyBackupPath to $(Get-ZLocationDatabaseFilePath), feel free to remove the old txt file"
Get-Content $legacyBackupPath | Where-Object { $_ -ne $null } | ForEach-Object {
$split = $_ -split "`t"
Add-ZDBLocation $split[0] $split[1]
}
}
}
}

Function Get-ZService {
,$service
}
Initialize-ZLocationDB
13 changes: 3 additions & 10 deletions ZLocation/ZLocation.Storage.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ Import-Module (Join-Path $PSScriptRoot 'ZLocation.Search.psm1')

function Get-ZLocation($Match)
{
$service = Get-ZService
$hash = [Collections.HashTable]::new()
foreach ($item in $service.Get())
foreach ($item in (Get-ZDBLocation))
{
$hash.add($item.path, $item.weight)
}
Expand All @@ -28,20 +27,14 @@ function Add-ZWeight {
[Parameter(Mandatory=$true)] [string]$Path,
[Parameter(Mandatory=$true)] [double]$Weight
)
$service = Get-ZService
$service.Add($path, $weight)
Update-ZDBLocation $path $weight
}

function Remove-ZLocation {
param (
[Parameter(Mandatory=$true)] [string]$Path
)
$service = Get-ZService
$service.Remove($path)
}

$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
Write-Warning "[ZLocation] module was removed, but service was not closed."
Remove-ZDBLocation $path
}

Export-ModuleMember -Function @("Get-ZLocation", "Add-ZWeight", "Remove-ZLocation")