Skip to content

Commit

Permalink
Feature: Add ability to search by size smaller or larger than a value…
Browse files Browse the repository at this point in the history
… (eg: `larger:1M` / `smaller:2.5M`)
  • Loading branch information
axllent committed Oct 26, 2024
1 parent bd47c19 commit 5675abe
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
54 changes: 54 additions & 0 deletions internal/storage/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"context"
"database/sql"
"encoding/json"
"fmt"
"regexp"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -397,6 +399,22 @@ func searchQueryBuilder(searchString, timezone string) *sqlf.Stmt {
}
}
}
} else if strings.HasPrefix(lw, "larger:") && sizeToBytes(cleanString(w[7:])) > 0 {
w = cleanString(w[7:])
size := sizeToBytes(w)
if exclude {
q.Where("Size < ?", size)
} else {
q.Where("Size > ?", size)
}
} else if strings.HasPrefix(lw, "smaller:") && sizeToBytes(cleanString(w[8:])) > 0 {
w = cleanString(w[8:])
size := sizeToBytes(w)
if exclude {
q.Where("Size > ?", size)
} else {
q.Where("Size < ?", size)
}
} else {
// search text
if exclude {
Expand All @@ -409,3 +427,39 @@ func searchQueryBuilder(searchString, timezone string) *sqlf.Stmt {

return q
}

// Simple function to return a size in bytes, eg 2kb, 4MB or 1.5m.
//
// K, k, Kb, KB, kB and kb are treated as Kilobytes.
// M, m, Mb, MB and mb are treated as Megabytes.
func sizeToBytes(v string) int64 {
v = strings.ToLower(v)
re := regexp.MustCompile(`^(\d+)(\.\d+)?\s?([a-z]{1,2})?$`)

m := re.FindAllStringSubmatch(v, -1)
if len(m) == 0 {
return 0
}

val := fmt.Sprintf("%s%s", m[0][1], m[0][2])
unit := m[0][3]

i, err := strconv.ParseFloat(strings.TrimSpace(val), 64)
if err != nil {
return 0
}

if unit == "" {
return int64(i)
}

if unit == "k" || unit == "kb" {
return int64(i * 1024)
}

if unit == "m" || unit == "mb" {
return int64(i * 1024 * 1024)
}

return 0
}
22 changes: 22 additions & 0 deletions internal/storage/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,25 @@ func TestEscPercentChar(t *testing.T) {
assertEqual(t, res, expected, "no match")
}
}

func TestSizeToBytes(t *testing.T) {
tests := map[string]int64{}
tests["1m"] = 1048576
tests["1mb"] = 1048576
tests["1 M"] = 1048576
tests["1 MB"] = 1048576
tests["1k"] = 1024
tests["1kb"] = 1024
tests["1 K"] = 1024
tests["1 kB"] = 1024
tests["1.5M"] = 1572864
tests["1234567890"] = 1234567890
tests["invalid"] = 0
tests["1.2.3"] = 0
tests["1.2.3M"] = 0

for search, expected := range tests {
res := sizeToBytes(search)
assertEqual(t, res, expected, "size does not match")
}
}

0 comments on commit 5675abe

Please sign in to comment.