peridot/peridot/db/psql/package.go

378 lines
11 KiB
Go

// Copyright (c) All respective contributors to the Peridot Project. All rights reserved.
// Copyright (c) 2021-2022 Rocky Enterprise Software Foundation, Inc. All rights reserved.
// Copyright (c) 2021-2022 Ctrl IQ, Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package serverpsql
import (
"github.com/lib/pq"
"peridot.resf.org/peridot/db/models"
peridotpb "peridot.resf.org/peridot/pb"
"peridot.resf.org/utils"
)
func (a *Access) GetPackagesInProject(filters *peridotpb.PackageFilters, projectId string, page int32, limit int32) (models.Packages, error) {
if filters == nil {
filters = &peridotpb.PackageFilters{}
}
var p models.Packages
err := a.query.Select(
&p,
`
select
p.id,
p.created_at,
p.updated_at,
p.name,
p.package_type,
proj_p.package_type_override,
(
select
ir.created_at
from import_revisions ir
where package_version_id = (
select
proj_pv.package_version_id
from project_package_versions proj_pv
where
proj_pv.package_id = p.id
and proj_pv.project_id = proj_p.project_id
and proj_pv.active = true
order by proj_pv.created_at desc limit 1
)
order by ir.created_at desc limit 1
) as last_import_at,
(
select
b.created_at
from builds b
inner join tasks t on t.id = b.task_id
where
t.status = 3
and package_version_id = (
select package_version_id
from project_package_versions proj_pv
where
proj_pv.package_id = p.id
and proj_pv.project_id = proj_p.project_id
and proj_pv.active = true
order by proj_pv.created_at desc limit 1
)
order by b.created_at desc limit 1
) as last_build_at,
count(p.*) over() as total
from packages p
inner join project_packages proj_p on proj_p.package_id = p.id
where
($1 :: uuid is null or p.id = $1 :: uuid)
and ($2 :: text is null or p.name ~* $2 :: text)
and ($3 :: bool is null or p.package_type in (6))
and ($4 :: text is null or p.name = $4 :: text)
and ($5 :: bool is null or (
select
ir.created_at
from import_revisions ir
where package_version_id = (
select
proj_pv.package_version_id
from project_package_versions proj_pv
where
proj_pv.package_id = p.id
and proj_pv.project_id = proj_p.project_id
and proj_pv.active = true
order by proj_pv.created_at desc limit 1
)
order by ir.created_at desc limit 1
) is null)
and ($6 :: bool is null or (
select
b.created_at
from builds b
inner join tasks t on t.id = b.task_id
where
t.status = 3
and package_version_id = (
select package_version_id
from project_package_versions proj_pv
where
proj_pv.package_id = p.id
and proj_pv.project_id = proj_p.project_id
and proj_pv.active = true
order by proj_pv.created_at desc limit 1
)
order by b.created_at desc limit 1
) is null)
and proj_p.project_id = $7 :: uuid
order by created_at desc, id
limit $8 offset $9
`,
utils.StringValueP(filters.Id),
utils.StringValueP(filters.Name),
utils.BoolValueP(filters.Modular),
utils.StringValueP(filters.NameExact),
utils.BoolValueP(filters.NoImports),
utils.BoolValueP(filters.NoBuilds),
projectId,
utils.UnlimitedLimit(limit),
utils.GetOffset(page, limit),
)
if err != nil {
return nil, err
}
return p, nil
}
func (a *Access) PackageCountInProject(projectId string) (int64, error) {
var ret int64
err := a.query.Get(&ret, "select count(*) from project_packages where project_id = $1", projectId)
return ret, err
}
func (a *Access) GetPackageVersion(packageVersionId string) (*models.PackageVersion, error) {
var ret models.PackageVersion
err := a.query.Get(
&ret,
`
select
pv.id,
pv.created_at,
pv.package_id,
pv.version,
pv.release
from package_versions pv
where pv.id = $1
`,
packageVersionId,
)
if err != nil {
return nil, err
}
return &ret, nil
}
func (a *Access) GetPackageVersionId(packageId string, version string, release string) (string, error) {
var id string
err := a.query.Get(&id, "select id from package_versions where package_id = $1 and version = $2 and release = $3", packageId, version, release)
if err != nil {
return "", err
}
return id, nil
}
func (a *Access) CreatePackageVersion(packageId string, version string, release string) (string, error) {
var id string
err := a.query.Get(
&id,
`
insert into package_versions (package_id, version, release)
values ($1, $2, $3)
returning id
`,
packageId,
version,
release,
)
if err != nil {
return "", err
}
return id, nil
}
func (a *Access) AttachPackageVersion(projectId string, packageId string, packageVersionId string, active bool) error {
_, err := a.query.Exec("insert into project_package_versions (project_id, package_id, package_version_id, active) values ($1, $2, $3, $4) on conflict do nothing", projectId, packageId, packageVersionId, active)
return err
}
func (a *Access) GetProjectPackageVersionFromPackageVersionId(packageVersionId string, projectId string) (string, error) {
var id string
err := a.query.Get(
&id,
`
select ppv.id
from project_package_versions ppv
inner join package_versions pv on pv.id = ppv.package_version_id
where
pv.id = $1
and ppv.project_id = $2
`,
packageVersionId,
projectId,
)
if err != nil {
return "", err
}
return id, nil
}
// DeactivateProjectPackageVersionByPackageIdAndProjectId deactivates all package versions for a project
func (a *Access) DeactivateProjectPackageVersionByPackageIdAndProjectId(packageId string, projectId string) error {
_, err := a.query.Exec("update project_package_versions set active = false where project_id = $1 and package_id = $2", projectId, packageId)
return err
}
func (a *Access) MakeActiveInRepoForPackageVersion(packageVersionId string, packageId string) error {
tx, err := a.Begin()
if err != nil {
return err
}
_, err = tx.Exec("update project_package_versions set active_in_repo = false where package_id = $1", packageId)
if err != nil {
return err
}
_, err = tx.Exec("update project_package_versions set active_in_repo = true where package_version_id = $1", packageVersionId)
if err != nil {
return err
}
return tx.Commit()
}
func (a *Access) CreatePackage(name string, packageType peridotpb.PackageType) (*models.Package, error) {
ret := models.Package{
Name: name,
PackageType: packageType,
}
err := a.query.Get(
&ret,
`
insert into packages (name, package_type)
values ($1, $2)
returning id, created_at, updated_at
`,
name,
packageType,
)
if err != nil {
return nil, err
}
return &ret, nil
}
func (a *Access) AddPackageToProject(projectId string, packageId string, packageTypeOverride peridotpb.PackageType) error {
_, err := a.query.Exec(
`
insert into project_packages (project_id, package_id, package_type_override)
values ($1, $2, $3)
on conflict on constraint project_packages_unique_entry do
update set package_type_override = $3
`,
projectId,
packageId,
packageTypeOverride,
)
return err
}
func (a *Access) GetPackageID(name string) (string, error) {
var id string
err := a.query.Get(&id, "select id from packages where name = $1", name)
if err != nil {
return "", err
}
return id, nil
}
func (a *Access) SetExtraOptionsForPackage(projectId string, packageName string, withFlags pq.StringArray, withoutFlags pq.StringArray) error {
if withFlags == nil {
withFlags = pq.StringArray{}
}
if withoutFlags == nil {
withoutFlags = pq.StringArray{}
}
_, err := a.query.Exec(
`
insert into extra_package_options (project_id, package_name, with_flags, without_flags)
values ($1, $2, $3, $4)
on conflict on constraint extra_package_options_uniq do
update set with_flags = $3, without_flags = $4, updated_at = now()
`,
projectId,
packageName,
withFlags,
withoutFlags,
)
return err
}
func (a *Access) GetExtraOptionsForPackage(projectId string, packageName string) (*models.ExtraOptions, error) {
var ret models.ExtraOptions
err := a.query.Get(
&ret,
"select id, created_at, updated_at, project_id, package_name, with_flags, without_flags, depends_on from extra_package_options where project_id = $1 and package_name = $2",
projectId,
packageName,
)
if err != nil {
return nil, err
}
return &ret, nil
}
func (a *Access) SetGroupInstallOptionsForPackage(projectId string, packageName string, dependsOn pq.StringArray) error {
if dependsOn == nil {
dependsOn = pq.StringArray{}
}
_, err := a.query.Exec(
`
insert into extra_package_options (project_id, package_name, depends_on)
values ($1, $2, $3)
on conflict on constraint extra_package_options_uniq do
update set depends_on = $3, updated_at = now()
`,
projectId,
packageName,
dependsOn,
)
return err
}
func (a *Access) SetPackageType(projectId string, packageName string, packageType peridotpb.PackageType) error {
_, err := a.query.Exec(
`
update project_packages set package_type_override = $3
where project_id = $1 and package_id = (select id from packages where name = $2)
`,
projectId,
packageName,
packageType,
)
return err
}