diff --git a/internal/models/resource.go b/internal/models/resource.go index aa51e47..0024d16 100644 --- a/internal/models/resource.go +++ b/internal/models/resource.go @@ -456,6 +456,30 @@ func (m *ResourceModel) FindByVersion(name string, resourceType string, version return resource, nil } +func (m *ResourceModel) BadgerDBFindByVersion(name string, resourceType string, version string) (types.Resource, error) { + key := []byte(fmt.Sprintf("/resources/%s/%s/%s", resourceType, name, version)) + + var resource types.Resource + err := m.DB.View(func(txn *badger.Txn) error { + item, err := txn.Get(key) + if err != nil { + if err == badger.ErrKeyNotFound { + return fmt.Errorf("resource with name %s, type %s and version %s not found", name, resourceType, version) + } + return err + } + + return item.Value(func(val []byte) error { + return json.Unmarshal(val, &resource) + }) + }) + if err != nil { + return types.Resource{}, err + } + + return resource, nil +} + /// A function that saves the driver result. This data is then stored in the metadata.driverresults.[driver] field of the resource and is arbitrary data types func (m *ResourceModel) SaveDriverResult(name string, resourceType string, driver string, result interface{}) error { diff --git a/internal/models/resource_test.go b/internal/models/resource_test.go index 765d965..6fb34da 100644 --- a/internal/models/resource_test.go +++ b/internal/models/resource_test.go @@ -376,6 +376,55 @@ func Test_Resource_FindAll(t *testing.T) { } +func Test_FindByVersion(t *testing.T) { + db := setupTestDB(t) + + resourcemodel := models.NewResourceModel(nil, db) + + resource := types.Resource{ + Name: "pipeline-1", + Resource: "pipe4", + Spec: map[string]interface{}{"key": "value"}, + } + + marshalResource, err := json.Marshal(resource) + if err != nil { + t.Fatalf("failed to marshal resource: %v", err) + } + + // Insert a resource to find by version + err = resourcemodel.BadgerDBInsert(resource.Name, resource.Resource, marshalResource) + if err != nil { + t.Fatalf("failed to insert resource: %v", err) + } + + // update the resource to create a new version + resource.Spec = map[string]interface{}{"key": "new value"} + + _, err = resourcemodel.BadgerDBUpdate(resource.Name, resource.Resource, resource) + if err != nil { + t.Fatalf("failed to update resource: %v", err) + } + + t.Run("Find Resource By Version", func(t *testing.T) { + foundResource, err := resourcemodel.BadgerDBFindByVersion(resource.Name, resource.Resource, "1") + if err != nil { + t.Fatalf("failed to find resource by version: %v", err) + } + + if foundResource.Name != resource.Name { + t.Errorf("expected resource name '%s', got '%s'", resource.Name, foundResource.Name) + } + if foundResource.Resource != resource.Resource { + t.Errorf("expected resource type '%s', got '%s'", resource.Resource, foundResource.Resource) + } + specMap := foundResource.Spec.(map[string]interface{}) + if specMap["key"] != "value" { + t.Errorf("expected spec key 'value', got '%s'", specMap["key"]) + } + }) +} + func Test_Resource_Update(t *testing.T) { db := setupTestDB(t)