package repositories import ( "database/sql" "simplycpq/models" ) type ValueRepository struct { db *sql.DB } func NewValueRepository(db *sql.DB) *ValueRepository { return &ValueRepository{ db: db, } } func (vr *ValueRepository) CreatePropertyTypeGroup(propertyTypeGroup *models.PropertyTypeGroup) (*models.PropertyTypeGroup, error) { // Implement the logic to insert the propertyTypeGroup into the database query := `INSERT INTO propertytypegroups(label, description, parentGroupId) VALUES($1,$2,$3) RETURNING id` rows, err := vr.db.Query(query, propertyTypeGroup.Label, propertyTypeGroup.Description, propertyTypeGroup.ParentGroupID) if err != nil { return nil, err } defer rows.Close() var id int if rows.Next() { err := rows.Scan(&id) if err != nil { return nil, err } } propertyTypeGroup.ID = id return propertyTypeGroup, nil } func (vr *ValueRepository) UpdatePropertyTypeGroup(propertyTypeGroup *models.PropertyTypeGroup) error { // Implement the logic to update the propertyTypeGroup in the database query := `UPDATE propertytypegroups SET label=$1, description=$2, parentGroupId=$3 WHERE id=$4` _, err := vr.db.Exec(query, propertyTypeGroup.Label, propertyTypeGroup.Description, propertyTypeGroup.ParentGroupID, propertyTypeGroup.ID) if err != nil { return err } return nil } func (vr *ValueRepository) DeletePropertyTypeGroup(id int) error { // Implement the logic to delete the propertyTypeGroup from the database query := `DELETE FROM propertytypegroups WHERE id=$1` _, err := vr.db.Exec(query, id) if err != nil { return err } return nil } func (vr *ValueRepository) GetPropertyTypeGroup(id int) (*models.PropertyTypeGroup, error) { // Implement the logic to retrieve the propertyTypeGroup from the database query := `SELECT id, label, description, parentGroupId FROM propertytypegroups WHERE id=$1` row := vr.db.QueryRow(query, id) var propertyTypeGroup models.PropertyTypeGroup err := row.Scan(&propertyTypeGroup.ID, &propertyTypeGroup.Label, &propertyTypeGroup.Description, &propertyTypeGroup.ParentGroupID) if err != nil { if err == sql.ErrNoRows { return nil, nil } return nil, err } return &propertyTypeGroup, nil } func (vr *ValueRepository) GetPropertyTypeGroupsByParentId(parentId int) ([]*models.PropertyTypeGroup, error) { // Implement the logic to retrieve the propertyTypeGroups by parentId from the database query := `SELECT id, label, description, parentGroupId FROM propertytypegroups WHERE parentGroupId=$1` rows, err := vr.db.Query(query, parentId) if err != nil { return nil, err } defer rows.Close() var propertyTypeGroups []*models.PropertyTypeGroup for rows.Next() { var propertyTypeGroup models.PropertyTypeGroup err := rows.Scan(&propertyTypeGroup.ID, &propertyTypeGroup.Label, &propertyTypeGroup.Description, &propertyTypeGroup.ParentGroupID) if err != nil { return nil, err } propertyTypeGroups = append(propertyTypeGroups, &propertyTypeGroup) } return propertyTypeGroups, nil } func (vr *ValueRepository) DeletePropertyTypeFromPropertyTypeGroupId(propertyTypeGroupId int) error { // Implement the logic to delete the propertyType from the propertyTypeGroup in the database query := `DELETE FROM propertytypes WHERE propertytypegroupid=$1` _, err := vr.db.Exec(query, propertyTypeGroupId) if err != nil { return err } return nil } func (vr *ValueRepository) CreatePropertyType(propertyType *models.PropertyType) (*models.PropertyType, error) { // Implement the logic to insert the propertyType into the database query := `INSERT INTO propertytypes(label, description, propertytypegroupid) VALUES($1,$2,$3) RETURNING id` err := vr.db.QueryRow(query, propertyType.Label, propertyType.Description, propertyType.PropertyTypeGroupID).Scan(&propertyType.ID) if err != nil { return nil, err } return propertyType, nil } func (vr *ValueRepository) UpdatePropertyType(propertyType *models.PropertyType) error { // Implement the logic to update the propertyType in the database query := `UPDATE propertytypes SET label=$1, description=$2, propertytypegroupid=$3 WHERE id=$4` _, err := vr.db.Exec(query, propertyType.Label, propertyType.Description, propertyType.PropertyTypeGroupID, propertyType.ID) if err != nil { return err } return nil } func (vr *ValueRepository) DeletePropertyType(id int) error { // Implement the logic to delete the propertyType from the database query := `DELETE FROM propertytypes WHERE id=$1` _, err := vr.db.Exec(query, id) if err != nil { return err } return nil } func (vr *ValueRepository) GetPropertyType(id int) (*models.PropertyType, error) { // Implement the logic to retrieve the propertyType from the database query := `SELECT id, label, description, propertytypegroupid FROM propertytypes WHERE id=$1` row := vr.db.QueryRow(query, id) var propertyType models.PropertyType err := row.Scan(&propertyType.ID, &propertyType.Label, &propertyType.Description, &propertyType.PropertyTypeGroupID) if err != nil { return nil, err } return &propertyType, nil } func (vr *ValueRepository) GetPropertyTypeIDByLabel(label string) (int, error) { // Implement the logic to retrieve the propertyType ID from the database by label query := `SELECT id FROM propertytypes WHERE label=$1` row := vr.db.QueryRow(query, label) var id int err := row.Scan(&id) if err != nil { return 0, err } return id, nil } func (vr *ValueRepository) GetPropertyTypesByGroupId(groupId int) ([]*models.PropertyType, error) { // Implement the logic to retrieve the propertyTypes by groupId from the database query := `SELECT id, label, description, propertytypegroupid FROM propertytypes WHERE propertytypegroupid=$1` rows, err := vr.db.Query(query, groupId) if err != nil { return nil, err } defer rows.Close() var propertyTypes []*models.PropertyType for rows.Next() { var propertyType models.PropertyType err := rows.Scan(&propertyType.ID, &propertyType.Label, &propertyType.Description, &propertyType.PropertyTypeGroupID) if err != nil { return nil, err } propertyTypes = append(propertyTypes, &propertyType) } if err = rows.Err(); err != nil { return nil, err } return propertyTypes, nil } func (vr *ValueRepository) CreateValueForPropertyTypeId(propertyTypeId int, value *models.Value) (*models.Value, error) { // Implement the logic to insert the value into the database for the given propertyTypeId query := `INSERT INTO values(propertyid, label, description) VALUES($1,$2,$3) RETURNING id` err := vr.db.QueryRow(query, propertyTypeId, value.Label, value.Description).Scan(&value.ID) if err != nil { return nil, err } return value, nil } func (vr *ValueRepository) DeleteValueFromPropertyTypeId(propertyTypeId int) error { // Implement the logic to delete the value from the database for the given propertyTypeId query := `DELETE FROM values WHERE propertid=$1` _, err := vr.db.Exec(query, propertyTypeId) if err != nil { return err } return nil } func (vr *ValueRepository) GetValuesFromPropertyTypeId(propertyTypeId int) ([]*models.Value, error) { // Implement the logic to retrieve the values from the database for the given propertyTypeId query := `SELECT id, label, description FROM values WHERE propertyid=$1` rows, err := vr.db.Query(query, propertyTypeId) if err != nil { return nil, err } defer rows.Close() var values []*models.Value for rows.Next() { var value models.Value err := rows.Scan(&value.ID, &value.Label, &value.Description) if err != nil { return nil, err } values = append(values, &value) } if err = rows.Err(); err != nil { return nil, err } return values, nil } func (vr *ValueRepository) CreatePropertyFromPropertyTypeId(propertyTypeId int, productGroupId int, productId int) (models.Property, error) { // Implement the logic to create a property from the given propertyTypeId query := `INSERT INTO properties(label, description, propertytypeid) SELECT label, description, id FROM propertytypes WHERE id=$1 RETURNING id, label, description` var property models.Property err := vr.db.QueryRow(query, propertyTypeId).Scan(&property.ID, &property.Label, &property.Description) if err != nil { return models.Property{}, err } property.PropertyTypeID = propertyTypeId property.ProductGroupID = productGroupId property.ProductID = productId err = vr.db.QueryRow(`UPDATE properties SET productgroupid=$1, productid=$2 WHERE id=$3 RETURNING id`, productGroupId, productId, property.ID).Scan(&property.ID) if err != nil { return models.Property{}, err } err = vr.copyValuesFromPropertyTypeToProperty(propertyTypeId, property.ID) if err != nil { return models.Property{}, err } return property, nil } func (vr *ValueRepository) GetValuesFromPropertyId(propertyId int) ([]*models.Value, error) { // Implement the logic to retrieve the values from the database for the given propertyId query := `SELECT id, label, description, propertyId FROM values WHERE propertyId=$1` rows, err := vr.db.Query(query, propertyId) if err != nil { return nil, err } defer rows.Close() var values []*models.Value for rows.Next() { var value models.Value err := rows.Scan(&value.ID, &value.Label, &value.Description, &value.PropertyID) if err != nil { return nil, err } values = append(values, &value) } if err = rows.Err(); err != nil { return nil, err } return values, nil } func (vr *ValueRepository) CreateValueForPropertyId(propertyId int, value *models.Value) (*models.Value, error) { // Implement the logic to create a value for the given propertyId query := `INSERT INTO values (propertyId, label, description) VALUES ($1, $2, $3) RETURNING id` err := vr.db.QueryRow(query, propertyId, value.Label, value.Description).Scan(&value.ID) if err != nil { return nil, err } return value, nil } func (vr *ValueRepository) DeleteValueFromPropertyId(valueId int, propertyId int) error { // Implement the logic to delete the value from the database for the given valueId and propertyId query := `DELETE FROM values WHERE id=$1 AND propertyId=$2` _, err := vr.db.Exec(query, valueId, propertyId) if err != nil { return err } return nil } func (vr *ValueRepository) GetValue(id int) (*models.Value, error) { // Implement the logic to retrieve the value from the database for the given id query := `SELECT id, label, description FROM values WHERE id=$1` row := vr.db.QueryRow(query, id) var value models.Value err := row.Scan(&value.ID, &value.Label, &value.Description) if err != nil { return nil, err } return &value, nil } func (vr *ValueRepository) createPropertyFromPropertyType(productGroupId int, productId int, propertyType *models.PropertyType) (*models.Property, error) { query := `INSERT INTO properties (label, description, propertytypeid, productid, productgroupid) VALUES ($1, $2, $3, $4, $5) RETURNING id` var property models.Property err := vr.db.QueryRow(query, propertyType.Label, propertyType.Description, propertyType.ID, productId, productGroupId).Scan(&property.ID) if err != nil { return nil, err } property.Label = propertyType.Label property.Description = propertyType.Description property.PropertyTypeID = propertyType.ID property.ProductID = productId property.ProductGroupID = productGroupId // Copy values from property type to property err = vr.copyValuesFromPropertyTypeToProperty(propertyType.ID, property.ID) if err != nil { return nil, err } return &property, nil } func (vr *ValueRepository) createPropertyFromProperty(productGroupId int, productId int, property *models.Property) (*models.Property, error) { query := `INSERT INTO properties (label, description, propertytypeid, productid, productgroupid) VALUES ($1, $2, $3, $4, $5) RETURNING id` var newProperty models.Property err := vr.db.QueryRow(query, property.Label, property.Description, property.PropertyTypeID, productId, productGroupId).Scan(&newProperty.ID) if err != nil { return nil, err } newProperty.Label = property.Label newProperty.Description = property.Description newProperty.PropertyTypeID = property.PropertyTypeID newProperty.ProductID = productId newProperty.ProductGroupID = productGroupId // Copy values from property type to property err = vr.copyValuesFromPropertyToProperty(property.ID, newProperty.ID) if err != nil { return nil, err } return &newProperty, nil } func (vr *ValueRepository) copyValuesFromPropertyTypeToProperty(propertyTypeId int, propertyId int) error { // Implement the logic to copy values from a property type to a property query := `INSERT INTO values (propertyId, label, description) SELECT $1, label, description FROM values WHERE propertyid=$2` _, err := vr.db.Exec(query, propertyId, propertyTypeId) if err != nil { return err } return nil } func (vr *ValueRepository) copyValuesFromPropertyToProperty(propertyIdFrom int, propertyIdTo int) error { // Implement the logic to copy values from one property to another query := `INSERT INTO values (propertyId, label, description) SELECT $1, label, description FROM values WHERE propertyId=$2` _, err := vr.db.Exec(query, propertyIdTo, propertyIdFrom) if err != nil { return err } return nil } func (vr *ValueRepository) CreateTerminalPropertyForProductGroupId(productGroupId int, propertyTypeId int, value string) error { // Create a new property for the given productGroupId and propertyTypeId propertyType, err := vr.GetPropertyType(propertyTypeId) if err != nil { return err } query := `INSERT INTO properties(label, description, propertytypeid, productgroupid, value) VALUES($1, $2, $3, $4) RETURNING id` var property models.Property err = vr.db.QueryRow(query, propertyType.Label, propertyType.Description, propertyTypeId, productGroupId).Scan(&property.ID) if err != nil { return err } err = vr.db.QueryRow(`INSERT INTO values(propertyid, label, description) VALUES($1, $2, $3) RETURNING id`, property.ID, value, "").Scan(&property.ID) if err != nil { return err } return nil } func (vr *ValueRepository) CreateTerminalPropertyForProductId(productId int, propertyTypeId int, value string) error { // Create a new property for the given productGroupId and propertyTypeId propertyType, err := vr.GetPropertyType(propertyTypeId) if err != nil { return err } query := `INSERT INTO properties(label, description, propertytypeid, productid, value) VALUES($1, $2, $3, $4, $5) RETURNING id` var property models.Property err = vr.db.QueryRow(query, propertyType.Label, propertyType.Description, propertyTypeId, productId, value).Scan(&property.ID) if err != nil { return err } err = vr.db.QueryRow(`INSERT INTO values(propertyid, label, description) VALUES($1, $2, $3) RETURNING id`, property.ID, value, "").Scan(&property.ID) if err != nil { return err } return nil } func (vr *ValueRepository) SetTerminalValueForProperty(propertyId int, value string) error { // Implement the logic to set a terminal value for a property // remove all values from the property _, err := vr.db.Exec(`DELETE FROM values WHERE propertyid=$1`, propertyId) if err != nil { return err } // add the new value to the property _, err = vr.db.Exec(`INSERT INTO values(propertyid, label, description) VALUES($1, $2, $3)`, propertyId, value, "") if err != nil { return err } return nil }