Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

### Features

- **scoop-search:** Use SQLite for caching apps to speed up local search ([#5851](https://github.com/ScoopInstaller/Scoop/issues/5851), [#5918](https://github.com/ScoopInstaller/Scoop/issues/5918), [#5946](https://github.com/ScoopInstaller/Scoop/issues/5946), [#5949](https://github.com/ScoopInstaller/Scoop/issues/5949), [#5955](https://github.com/ScoopInstaller/Scoop/issues/5955), [#5966](https://github.com/ScoopInstaller/Scoop/issues/5966))
- **scoop-search:** Use SQLite for caching apps to speed up local search ([#5851](https://github.com/ScoopInstaller/Scoop/issues/5851), [#5918](https://github.com/ScoopInstaller/Scoop/issues/5918), [#5946](https://github.com/ScoopInstaller/Scoop/issues/5946), [#5949](https://github.com/ScoopInstaller/Scoop/issues/5949), [#5955](https://github.com/ScoopInstaller/Scoop/issues/5955), [#5966](https://github.com/ScoopInstaller/Scoop/issues/5966), [#5967](https://github.com/ScoopInstaller/Scoop/issues/5967))
- **core:** New cache filename format ([#5929](https://github.com/ScoopInstaller/Scoop/issues/5929))

### Bug Fixes
Expand Down
5 changes: 5 additions & 0 deletions lib/buckets.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ function rm_bucket($name) {
}

Remove-Item $dir -Recurse -Force -ErrorAction Stop
if (get_config USE_SQLITE_CACHE) {
info 'Updating cache...'
Remove-ScoopDBItem -Bucket $name
}
success "The $name bucket was removed successfully."
return 0
}

Expand Down
75 changes: 69 additions & 6 deletions lib/database.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ function Open-ScoopDB {
suggest TEXT,
PRIMARY KEY (name, version, bucket)
)"
$tableCommand.CommandType = [System.Data.CommandType]::Text
$tableCommand.ExecuteNonQuery() | Out-Null
$tableCommand.Dispose()
return $db
Expand All @@ -88,7 +89,7 @@ function Open-ScoopDB {
.SYNOPSIS
Set Scoop database item(s).
.DESCRIPTION
Insert or replace Scoop database item(s) into the database.
Insert or replace item(s) into the Scoop SQLite database.
.PARAMETER InputObject
System.Object[]
The database item(s) to insert or replace.
Expand All @@ -113,6 +114,7 @@ function Set-ScoopDBItem {
$dbQuery = "INSERT OR REPLACE INTO app ($($colName -join ', ')) VALUES ($('@' + ($colName -join ', @')))"
$dbCommand = $db.CreateCommand()
$dbCommand.CommandText = $dbQuery
$dbCommand.CommandType = [System.Data.CommandType]::Text
}
process {
foreach ($item in $InputObject) {
Expand Down Expand Up @@ -161,7 +163,7 @@ function Set-ScoopDB {
)

begin {
$list = [System.Collections.Generic.List[PSCustomObject]]::new()
$list = [System.Collections.Generic.List[psobject]]::new()
$arch = Get-DefaultArchitecture
}
process {
Expand Down Expand Up @@ -220,11 +222,14 @@ function Set-ScoopDB {
.SYNOPSIS
Select Scoop database item(s).
.DESCRIPTION
Select Scoop database item(s) from the database.
Select item(s) from the Scoop SQLite database.
The pattern is matched against the name, binaries, and shortcuts columns for apps.
.PARAMETER Pattern
System.String
The pattern to search for. If is an empty string, all items will be returned.
.PARAMETER From
System.String[]
The fields to search from.
.INPUTS
System.String
.OUTPUTS
Expand All @@ -239,6 +244,7 @@ function Select-ScoopDBItem {
[string]
$Pattern,
[Parameter(Mandatory, Position = 1)]
[ValidateNotNullOrEmpty()]
[string[]]
$From
)
Expand All @@ -252,10 +258,10 @@ function Select-ScoopDBItem {
$dbCommand = $db.CreateCommand()
$dbCommand.CommandText = $dbQuery
$dbCommand.CommandType = [System.Data.CommandType]::Text
$dbAdapter.SelectCommand = $dbCommand
}
process {
$dbCommand.Parameters.AddWithValue('@Pattern', $(if ($Pattern -eq '') { '%' } else { '%' + $Pattern + '%' })) | Out-Null
$dbAdapter.SelectCommand = $dbCommand
[void]$dbAdapter.Fill($result)
}
end {
Expand All @@ -269,7 +275,7 @@ function Select-ScoopDBItem {
.SYNOPSIS
Get Scoop database item.
.DESCRIPTION
Get Scoop database item from the database.
Get item from the Scoop SQLite database.
.PARAMETER Name
System.String
The name of the item to get.
Expand Down Expand Up @@ -312,12 +318,12 @@ function Get-ScoopDBItem {
$dbCommand = $db.CreateCommand()
$dbCommand.CommandText = $dbQuery
$dbCommand.CommandType = [System.Data.CommandType]::Text
$dbAdapter.SelectCommand = $dbCommand
}
process {
$dbCommand.Parameters.AddWithValue('@Name', $Name) | Out-Null
$dbCommand.Parameters.AddWithValue('@Bucket', $Bucket) | Out-Null
$dbCommand.Parameters.AddWithValue('@Version', $Version) | Out-Null
$dbAdapter.SelectCommand = $dbCommand
[void]$dbAdapter.Fill($result)
}
end {
Expand All @@ -326,3 +332,60 @@ function Get-ScoopDBItem {
return $result
}
}

<#
.SYNOPSIS
Remove Scoop database item(s).
.DESCRIPTION
Remove item(s) from the Scoop SQLite database.
.PARAMETER Name
System.String
The name of the item to remove.
.PARAMETER Bucket
System.String
The bucket of the item to remove.
.INPUTS
System.String
.OUTPUTS
None
#>
function Remove-ScoopDBItem {
[CmdletBinding()]
param (
[Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[string]
$Name,
[Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
[string]
$Bucket
)

begin {
$db = Open-ScoopDB
$dbTrans = $db.BeginTransaction()
$dbQuery = 'DELETE FROM app WHERE bucket = @Bucket'
$dbCommand = $db.CreateCommand()
$dbCommand.CommandText = $dbQuery
$dbCommand.CommandType = [System.Data.CommandType]::Text
}
process {
$dbCommand.Parameters.AddWithValue('@Bucket', $Bucket) | Out-Null
if ($Name) {
$dbCommand.CommandText = $dbQuery + ' AND name = @Name'
$dbCommand.Parameters.AddWithValue('@Name', $Name) | Out-Null
}
$dbCommand.ExecuteNonQuery() | Out-Null
}
end {
try {
$dbTrans.Commit()
} catch {
$dbTrans.Rollback()
throw $_
} finally {
$dbCommand.Dispose()
$dbTrans.Dispose()
$db.Dispose()
}
}
}
40 changes: 32 additions & 8 deletions libexec/scoop-update.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ function Sync-Bucket {

$buckets | Where-Object { !$_.valid } | ForEach-Object { Write-Host "'$($_.name)' is not a git repository. Skipped." }

$updatedFiles = [System.Collections.ArrayList]::Synchronized([System.Collections.ArrayList]::new())
$updatedFiles = [System.Collections.Generic.SynchronizedCollection[string]]::new()
$removedFiles = [System.Collections.Generic.SynchronizedCollection[psobject]]::new()
if ($PSVersionTable.PSVersion.Major -ge 7) {
# Parallel parameter is available since PowerShell 7
$buckets | Where-Object { $_.valid } | ForEach-Object -ThrottleLimit 5 -Parallel {
Expand All @@ -198,10 +199,21 @@ function Sync-Bucket {
Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit
}
if (get_config USE_SQLITE_CACHE) {
Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', '--diff-filter=d', $previousCommit) | ForEach-Object {
$filePath = Join-Path $bucketLoc $_
Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-status', $previousCommit) | ForEach-Object {
$status, $file = $_ -split '\s+', 2
$filePath = Join-Path $bucketLoc $file
if ($filePath -match "^$([regex]::Escape($innerBucketLoc)).*\.json$") {
[void]($using:updatedFiles).Add($filePath)
switch ($status) {
{ $_ -in 'A', 'M', 'R' } {
[void]($using:updatedFiles).Add($filePath)
}
'D' {
[void]($using:removedFiles).Add([pscustomobject]@{
Name = ([System.IO.FileInfo]$file).BaseName
Bucket = $name
})
}
}
}
}
}
Expand All @@ -218,18 +230,30 @@ function Sync-Bucket {
Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit
}
if (get_config USE_SQLITE_CACHE) {
Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', '--diff-filter=d', $previousCommit) | ForEach-Object {
$filePath = Join-Path $bucketLoc $_
Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-status', $previousCommit) | ForEach-Object {
$status, $file = $_ -split '\s+', 2
$filePath = Join-Path $bucketLoc $file
if ($filePath -match "^$([regex]::Escape($innerBucketLoc)).*\.json$") {
[void]($updatedFiles).Add($filePath)
switch ($status) {
{ $_ -in 'A', 'M', 'R' } {
[void]($updatedFiles).Add($filePath)
}
'D' {
[void]($removedFiles).Add([pscustomobject]@{
Name = ([System.IO.FileInfo]$file).BaseName
Bucket = $name
})
}
}
}
}
}
}
}
if ((get_config USE_SQLITE_CACHE) -and ($updatedFiles.Count -gt 0)) {
if ((get_config USE_SQLITE_CACHE) -and ($updatedFiles.Count -gt 0 -or $removedFiles.Count -gt 0)) {
info 'Updating cache...'
Set-ScoopDB -Path $updatedFiles
$removedFiles | Remove-ScoopDBItem
}
}

Expand Down