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

[LevelDB IndexedDB] Return empty rows instead of error when db or object store doesn't exist #1830

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
11 changes: 9 additions & 2 deletions ee/indexeddb/indexeddb.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"path/filepath"

"github.com/kolide/goleveldb/leveldb"
leveldberrors "github.com/kolide/goleveldb/leveldb/errors"
"github.com/kolide/goleveldb/leveldb/opt"
"github.com/kolide/launcher/ee/agent"
)
Expand Down Expand Up @@ -41,6 +42,8 @@ func QueryIndexeddbObjectStore(dbLocation string, dbName string, objectStoreName
// The copy was successful -- make sure we clean it up after we're done
defer os.RemoveAll(tempDbCopyLocation)

objs := make([]map[string][]byte, 0)

opts := &opt.Options{
Comparer: indexeddbComparer,
DisableSeeksCompaction: true, // no need to perform compaction
Expand All @@ -64,6 +67,10 @@ func QueryIndexeddbObjectStore(dbLocation string, dbName string, objectStoreName
}
databaseIdRaw, err := db.Get(databaseNameKey, nil)
if err != nil {
// If the database doesn't exist, return an empty list of objects
if errors.Is(err, leveldberrors.ErrNotFound) {
return objs, nil
}
return nil, fmt.Errorf("querying for database id: %w", err)
}
databaseId, _ := binary.Uvarint(databaseIdRaw)
Expand All @@ -88,14 +95,14 @@ func QueryIndexeddbObjectStore(dbLocation string, dbName string, objectStoreName
}

if objectStoreId == 0 {
return nil, errors.New("unable to get object store ID")
// If the object store doesn't exist, return an empty list of objects
return objs, nil
}

// Get the key prefix for all objects in this store.
keyPrefix := objectDataKeyPrefix(databaseId, objectStoreId)

// Now, we can read all records, keeping only the ones with our matching key prefix.
objs := make([]map[string][]byte, 0)
iter := db.NewIterator(nil, nil)
for iter.Next() {
key := iter.Key()
Expand Down
20 changes: 19 additions & 1 deletion ee/katc/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,22 +156,40 @@ func TestQueryChromeIndexedDB(t *testing.T) {
// indexeddb_leveldb.go and the ee/indexeddb package.

for _, tt := range []struct {
testName string
fileName string
dbName string
objStoreName string
expectedRows int
zipBytes []byte
}{
{
testName: "file__0.indexeddb.leveldb.zip",
fileName: "file__0.indexeddb.leveldb.zip",
dbName: "launchertestdb",
objStoreName: "launchertestobjstore",
expectedRows: 2,
zipBytes: basicChromeIndexeddb,
},
{
testName: "file__0.indexeddb.leveldb.zip -- db does not exist",
fileName: "file__0.indexeddb.leveldb.zip",
dbName: "not-the-correct-db-name",
objStoreName: "launchertestobjstore",
expectedRows: 0,
zipBytes: basicChromeIndexeddb,
},
{
testName: "file__0.indexeddb.leveldb.zip -- object store does not exist",
fileName: "file__0.indexeddb.leveldb.zip",
dbName: "launchertestdb",
objStoreName: "not-the-correct-obj-store-name",
expectedRows: 0,
zipBytes: basicChromeIndexeddb,
},
} {
tt := tt
t.Run(tt.fileName, func(t *testing.T) {
t.Run(tt.testName, func(t *testing.T) {
t.Parallel()

// Write zip bytes to file
Expand Down
Loading