feat: Add project API endpoints (#51)

* feat: Add project models

* Add project query functions

* Add organization parameter query

* Add project URL parameter parse

* Add project create and list endpoints

* Add test for organization provided

* Remove unimplemented routes

* Decrease conn timeout

* Add test for UnbiasedModulo32

* Fix expected value

* Add single user endpoint

* Add query for project versions

* Fix linting errors

* Add comments

* Add test for invalid archive

* Check unauthenticated endpoints

* Add check if no change happened

* Ensure context close ends listener

* Fix parallel test run

* Test empty

* Fix organization param comment
This commit is contained in:
Kyle Carberry
2022-01-24 17:07:42 +00:00
committed by GitHub
parent 52e50fc9ca
commit a44056cff5
37 changed files with 2121 additions and 22 deletions
+122
View File
@@ -3,6 +3,9 @@ package databasefake
import (
"context"
"database/sql"
"strings"
"github.com/google/uuid"
"github.com/coder/coder/database"
)
@@ -14,15 +17,25 @@ func New() database.Store {
organizations: make([]database.Organization, 0),
organizationMembers: make([]database.OrganizationMember, 0),
users: make([]database.User, 0),
project: make([]database.Project, 0),
projectHistory: make([]database.ProjectHistory, 0),
projectParameter: make([]database.ProjectParameter, 0),
}
}
// fakeQuerier replicates database functionality to enable quick testing.
type fakeQuerier struct {
// Legacy tables
apiKeys []database.APIKey
organizations []database.Organization
organizationMembers []database.OrganizationMember
users []database.User
// New tables
project []database.Project
projectHistory []database.ProjectHistory
projectParameter []database.ProjectParameter
}
// InTx doesn't rollback data properly for in-memory yet.
@@ -89,6 +102,62 @@ func (q *fakeQuerier) GetOrganizationsByUserID(_ context.Context, userID string)
return organizations, nil
}
func (q *fakeQuerier) GetProjectByOrganizationAndName(_ context.Context, arg database.GetProjectByOrganizationAndNameParams) (database.Project, error) {
for _, project := range q.project {
if project.OrganizationID != arg.OrganizationID {
continue
}
if !strings.EqualFold(project.Name, arg.Name) {
continue
}
return project, nil
}
return database.Project{}, sql.ErrNoRows
}
func (q *fakeQuerier) GetProjectHistoryByProjectID(_ context.Context, projectID uuid.UUID) ([]database.ProjectHistory, error) {
history := make([]database.ProjectHistory, 0)
for _, projectHistory := range q.projectHistory {
if projectHistory.ProjectID.String() != projectID.String() {
continue
}
history = append(history, projectHistory)
}
if len(history) == 0 {
return nil, sql.ErrNoRows
}
return history, nil
}
func (q *fakeQuerier) GetProjectsByOrganizationIDs(_ context.Context, ids []string) ([]database.Project, error) {
projects := make([]database.Project, 0)
for _, project := range q.project {
for _, id := range ids {
if project.OrganizationID == id {
projects = append(projects, project)
break
}
}
}
if len(projects) == 0 {
return nil, sql.ErrNoRows
}
return projects, nil
}
func (q *fakeQuerier) GetOrganizationMemberByUserID(_ context.Context, arg database.GetOrganizationMemberByUserIDParams) (database.OrganizationMember, error) {
for _, organizationMember := range q.organizationMembers {
if organizationMember.OrganizationID != arg.OrganizationID {
continue
}
if organizationMember.UserID != arg.UserID {
continue
}
return organizationMember, nil
}
return database.OrganizationMember{}, sql.ErrNoRows
}
func (q *fakeQuerier) InsertAPIKey(_ context.Context, arg database.InsertAPIKeyParams) (database.APIKey, error) {
//nolint:gosimple
key := database.APIKey{
@@ -136,6 +205,59 @@ func (q *fakeQuerier) InsertOrganizationMember(_ context.Context, arg database.I
return organizationMember, nil
}
func (q *fakeQuerier) InsertProject(_ context.Context, arg database.InsertProjectParams) (database.Project, error) {
project := database.Project{
ID: arg.ID,
CreatedAt: arg.CreatedAt,
UpdatedAt: arg.UpdatedAt,
OrganizationID: arg.OrganizationID,
Name: arg.Name,
Provisioner: arg.Provisioner,
}
q.project = append(q.project, project)
return project, nil
}
func (q *fakeQuerier) InsertProjectHistory(_ context.Context, arg database.InsertProjectHistoryParams) (database.ProjectHistory, error) {
//nolint:gosimple
history := database.ProjectHistory{
ID: arg.ID,
ProjectID: arg.ProjectID,
CreatedAt: arg.CreatedAt,
UpdatedAt: arg.UpdatedAt,
Name: arg.Name,
Description: arg.Description,
StorageMethod: arg.StorageMethod,
StorageSource: arg.StorageSource,
ImportJobID: arg.ImportJobID,
}
q.projectHistory = append(q.projectHistory, history)
return history, nil
}
func (q *fakeQuerier) InsertProjectParameter(_ context.Context, arg database.InsertProjectParameterParams) (database.ProjectParameter, error) {
//nolint:gosimple
param := database.ProjectParameter{
ID: arg.ID,
CreatedAt: arg.CreatedAt,
ProjectHistoryID: arg.ProjectHistoryID,
Name: arg.Name,
Description: arg.Description,
DefaultSource: arg.DefaultSource,
AllowOverrideSource: arg.AllowOverrideSource,
DefaultDestination: arg.DefaultDestination,
AllowOverrideDestination: arg.AllowOverrideDestination,
DefaultRefresh: arg.DefaultRefresh,
RedisplayValue: arg.RedisplayValue,
ValidationError: arg.ValidationError,
ValidationCondition: arg.ValidationCondition,
ValidationTypeSystem: arg.ValidationTypeSystem,
ValidationValueType: arg.ValidationValueType,
}
q.projectParameter = append(q.projectParameter, param)
return param, nil
}
func (q *fakeQuerier) InsertUser(_ context.Context, arg database.InsertUserParams) (database.User, error) {
user := database.User{
ID: arg.ID,
+77
View File
@@ -6,6 +6,19 @@ CREATE TYPE login_type AS ENUM (
'oidc'
);
CREATE TYPE parameter_type_system AS ENUM (
'hcl'
);
CREATE TYPE project_storage_method AS ENUM (
'inline-archive'
);
CREATE TYPE provisioner_type AS ENUM (
'terraform',
'cdr-basic'
);
CREATE TYPE userstatus AS ENUM (
'active',
'dormant',
@@ -57,6 +70,46 @@ CREATE TABLE organizations (
workspace_auto_off boolean DEFAULT false NOT NULL
);
CREATE TABLE project (
id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
organization_id text NOT NULL,
name character varying(64) NOT NULL,
provisioner provisioner_type NOT NULL,
active_version_id uuid
);
CREATE TABLE project_history (
id uuid NOT NULL,
project_id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
name character varying(64) NOT NULL,
description character varying(1048576) NOT NULL,
storage_method project_storage_method NOT NULL,
storage_source bytea NOT NULL,
import_job_id uuid NOT NULL
);
CREATE TABLE project_parameter (
id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
project_history_id uuid NOT NULL,
name character varying(64) NOT NULL,
description character varying(8192) DEFAULT ''::character varying NOT NULL,
default_source text,
allow_override_source boolean NOT NULL,
default_destination text,
allow_override_destination boolean NOT NULL,
default_refresh text NOT NULL,
redisplay_value boolean NOT NULL,
validation_error character varying(256) NOT NULL,
validation_condition character varying(512) NOT NULL,
validation_type_system parameter_type_system NOT NULL,
validation_value_type character varying(64) NOT NULL
);
CREATE TABLE users (
id text NOT NULL,
email text NOT NULL,
@@ -79,3 +132,27 @@ CREATE TABLE users (
shell text DEFAULT ''::text NOT NULL
);
ALTER TABLE ONLY project_history
ADD CONSTRAINT project_history_id_key UNIQUE (id);
ALTER TABLE ONLY project_history
ADD CONSTRAINT project_history_project_id_name_key UNIQUE (project_id, name);
ALTER TABLE ONLY project
ADD CONSTRAINT project_id_key UNIQUE (id);
ALTER TABLE ONLY project
ADD CONSTRAINT project_organization_id_name_key UNIQUE (organization_id, name);
ALTER TABLE ONLY project_parameter
ADD CONSTRAINT project_parameter_id_key UNIQUE (id);
ALTER TABLE ONLY project_parameter
ADD CONSTRAINT project_parameter_project_history_id_name_key UNIQUE (project_history_id, name);
ALTER TABLE ONLY project_history
ADD CONSTRAINT project_history_project_id_fkey FOREIGN KEY (project_id) REFERENCES project(id);
ALTER TABLE ONLY project_parameter
ADD CONSTRAINT project_parameter_project_history_id_fkey FOREIGN KEY (project_history_id) REFERENCES project_history(id) ON DELETE CASCADE;
+25 -8
View File
@@ -20,12 +20,29 @@ func TestMain(m *testing.M) {
func TestMigrate(t *testing.T) {
t.Parallel()
connection, closeFn, err := postgres.Open()
require.NoError(t, err)
defer closeFn()
db, err := sql.Open("postgres", connection)
require.NoError(t, err)
defer db.Close()
err = database.Migrate(db)
require.NoError(t, err)
t.Run("Once", func(t *testing.T) {
t.Parallel()
connection, closeFn, err := postgres.Open()
require.NoError(t, err)
defer closeFn()
db, err := sql.Open("postgres", connection)
require.NoError(t, err)
defer db.Close()
err = database.Migrate(db)
require.NoError(t, err)
})
t.Run("Twice", func(t *testing.T) {
t.Parallel()
connection, closeFn, err := postgres.Open()
require.NoError(t, err)
defer closeFn()
db, err := sql.Open("postgres", connection)
require.NoError(t, err)
defer db.Close()
err = database.Migrate(db)
require.NoError(t, err)
err = database.Migrate(db)
require.NoError(t, err)
})
}
@@ -0,0 +1,84 @@
CREATE TYPE provisioner_type AS ENUM ('terraform', 'cdr-basic');
-- Project defines infrastructure that your software project
-- requires for development.
CREATE TABLE project (
id uuid NOT NULL UNIQUE,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
-- Projects must be scoped to an organization.
organization_id text NOT NULL,
name varchar(64) NOT NULL,
provisioner provisioner_type NOT NULL,
-- Target's a Project Version to use for Workspaces.
-- If a Workspace doesn't match this version, it will be prompted to rebuild.
active_version_id uuid,
-- Disallow projects to have the same name under
-- the same organization.
UNIQUE(organization_id, name)
);
CREATE TYPE project_storage_method AS ENUM ('inline-archive');
-- Project Versions store Project history. When a Project Version is imported,
-- an "import" job is queued to parse parameters. A Project Version
-- can only be used if the import job succeeds.
CREATE TABLE project_history (
id uuid NOT NULL UNIQUE,
-- This should be indexed.
project_id uuid NOT NULL REFERENCES project (id),
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
-- Name is generated for ease of differentiation.
-- eg. TheCozyRabbit16
name varchar(64) NOT NULL,
-- Extracted from a README.md on import.
-- Maximum of 1MB.
description varchar(1048576) NOT NULL,
storage_method project_storage_method NOT NULL,
storage_source bytea NOT NULL,
-- The import job for a Project Version. This is used
-- to detect if an import was successful.
import_job_id uuid NOT NULL,
-- Disallow projects to have the same build name
-- multiple times.
UNIQUE(project_id, name)
);
-- Types of parameters the automator supports.
CREATE TYPE parameter_type_system AS ENUM ('hcl');
-- Stores project version parameters parsed on import.
-- No secrets are stored here.
--
-- All parameter validation occurs server-side to process
-- complex validations.
--
-- Parameter types, description, and validation will produce
-- a UI for users to enter values.
-- Needs to be made consistent with the examples below.
CREATE TABLE project_parameter (
id uuid NOT NULL UNIQUE,
created_at timestamptz NOT NULL,
project_history_id uuid NOT NULL REFERENCES project_history(id) ON DELETE CASCADE,
name varchar(64) NOT NULL,
-- 8KB limit
description varchar(8192) NOT NULL DEFAULT '',
-- eg. data://inlinevalue
default_source text,
-- Allows the user to override the source.
allow_override_source boolean NOT null,
-- eg. env://SOME_VARIABLE, tfvars://example
default_destination text,
-- Allows the user to override the destination.
allow_override_destination boolean NOT null,
default_refresh text NOT NULL,
-- Whether the consumer can view the source and destinations.
redisplay_value boolean NOT null,
-- This error would appear in the UI if the condition is not met.
validation_error varchar(256) NOT NULL,
validation_condition varchar(512) NOT NULL,
validation_type_system parameter_type_system NOT NULL,
validation_value_type varchar(64) NOT NULL,
UNIQUE(project_history_id, name)
);
+98
View File
@@ -3,9 +3,12 @@
package database
import (
"database/sql"
"encoding/json"
"fmt"
"time"
"github.com/google/uuid"
)
type LoginType string
@@ -28,6 +31,61 @@ func (e *LoginType) Scan(src interface{}) error {
return nil
}
type ParameterTypeSystem string
const (
ParameterTypeSystemHCL ParameterTypeSystem = "hcl"
)
func (e *ParameterTypeSystem) Scan(src interface{}) error {
switch s := src.(type) {
case []byte:
*e = ParameterTypeSystem(s)
case string:
*e = ParameterTypeSystem(s)
default:
return fmt.Errorf("unsupported scan type for ParameterTypeSystem: %T", src)
}
return nil
}
type ProjectStorageMethod string
const (
ProjectStorageMethodInlineArchive ProjectStorageMethod = "inline-archive"
)
func (e *ProjectStorageMethod) Scan(src interface{}) error {
switch s := src.(type) {
case []byte:
*e = ProjectStorageMethod(s)
case string:
*e = ProjectStorageMethod(s)
default:
return fmt.Errorf("unsupported scan type for ProjectStorageMethod: %T", src)
}
return nil
}
type ProvisionerType string
const (
ProvisionerTypeTerraform ProvisionerType = "terraform"
ProvisionerTypeCdrBasic ProvisionerType = "cdr-basic"
)
func (e *ProvisionerType) Scan(src interface{}) error {
switch s := src.(type) {
case []byte:
*e = ProvisionerType(s)
case string:
*e = ProvisionerType(s)
default:
return fmt.Errorf("unsupported scan type for ProvisionerType: %T", src)
}
return nil
}
type UserStatus string
const (
@@ -93,6 +151,46 @@ type OrganizationMember struct {
Roles []string `db:"roles" json:"roles"`
}
type Project struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
OrganizationID string `db:"organization_id" json:"organization_id"`
Name string `db:"name" json:"name"`
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
ActiveVersionID uuid.NullUUID `db:"active_version_id" json:"active_version_id"`
}
type ProjectHistory struct {
ID uuid.UUID `db:"id" json:"id"`
ProjectID uuid.UUID `db:"project_id" json:"project_id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Name string `db:"name" json:"name"`
Description string `db:"description" json:"description"`
StorageMethod ProjectStorageMethod `db:"storage_method" json:"storage_method"`
StorageSource []byte `db:"storage_source" json:"storage_source"`
ImportJobID uuid.UUID `db:"import_job_id" json:"import_job_id"`
}
type ProjectParameter struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
ProjectHistoryID uuid.UUID `db:"project_history_id" json:"project_history_id"`
Name string `db:"name" json:"name"`
Description string `db:"description" json:"description"`
DefaultSource sql.NullString `db:"default_source" json:"default_source"`
AllowOverrideSource bool `db:"allow_override_source" json:"allow_override_source"`
DefaultDestination sql.NullString `db:"default_destination" json:"default_destination"`
AllowOverrideDestination bool `db:"allow_override_destination" json:"allow_override_destination"`
DefaultRefresh string `db:"default_refresh" json:"default_refresh"`
RedisplayValue bool `db:"redisplay_value" json:"redisplay_value"`
ValidationError string `db:"validation_error" json:"validation_error"`
ValidationCondition string `db:"validation_condition" json:"validation_condition"`
ValidationTypeSystem ParameterTypeSystem `db:"validation_type_system" json:"validation_type_system"`
ValidationValueType string `db:"validation_value_type" json:"validation_value_type"`
}
type User struct {
ID string `db:"id" json:"id"`
Email string `db:"email" json:"email"`
+17
View File
@@ -18,6 +18,7 @@ func TestPubsub(t *testing.T) {
t.Parallel()
t.Run("Postgres", func(t *testing.T) {
t.Parallel()
ctx, cancelFunc := context.WithCancel(context.Background())
defer cancelFunc()
@@ -45,4 +46,20 @@ func TestPubsub(t *testing.T) {
message := <-messageChannel
assert.Equal(t, string(message), data)
})
t.Run("PostgresCloseCancel", func(t *testing.T) {
t.Parallel()
ctx, cancelFunc := context.WithCancel(context.Background())
defer cancelFunc()
connectionURL, close, err := postgres.Open()
require.NoError(t, err)
defer close()
db, err := sql.Open("postgres", connectionURL)
require.NoError(t, err)
defer db.Close()
pubsub, err := database.NewPubsub(ctx, db, connectionURL)
require.NoError(t, err)
defer pubsub.Close()
cancelFunc()
})
}
+9
View File
@@ -4,18 +4,27 @@ package database
import (
"context"
"github.com/google/uuid"
)
type querier interface {
GetAPIKeyByID(ctx context.Context, id string) (APIKey, error)
GetOrganizationByName(ctx context.Context, name string) (Organization, error)
GetOrganizationMemberByUserID(ctx context.Context, arg GetOrganizationMemberByUserIDParams) (OrganizationMember, error)
GetOrganizationsByUserID(ctx context.Context, userID string) ([]Organization, error)
GetProjectByOrganizationAndName(ctx context.Context, arg GetProjectByOrganizationAndNameParams) (Project, error)
GetProjectHistoryByProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectHistory, error)
GetProjectsByOrganizationIDs(ctx context.Context, ids []string) ([]Project, error)
GetUserByEmailOrUsername(ctx context.Context, arg GetUserByEmailOrUsernameParams) (User, error)
GetUserByID(ctx context.Context, id string) (User, error)
GetUserCount(ctx context.Context) (int64, error)
InsertAPIKey(ctx context.Context, arg InsertAPIKeyParams) (APIKey, error)
InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, error)
InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error)
InsertProject(ctx context.Context, arg InsertProjectParams) (Project, error)
InsertProjectHistory(ctx context.Context, arg InsertProjectHistoryParams) (ProjectHistory, error)
InsertProjectParameter(ctx context.Context, arg InsertProjectParameterParams) (ProjectParameter, error)
InsertUser(ctx context.Context, arg InsertUserParams) (User, error)
UpdateAPIKeyByID(ctx context.Context, arg UpdateAPIKeyByIDParams) error
}
+140 -6
View File
@@ -42,12 +42,67 @@ FROM
users;
-- name: GetOrganizationByName :one
SELECT * FROM organizations WHERE name = $1 LIMIT 1;
SELECT
*
FROM
organizations
WHERE
name = $1
LIMIT
1;
-- name: GetOrganizationsByUserID :many
SELECT * FROM organizations WHERE id = (
SELECT organization_id FROM organization_members WHERE user_id = $1
);
SELECT
*
FROM
organizations
WHERE
id = (
SELECT
organization_id
FROM
organization_members
WHERE
user_id = $1
);
-- name: GetOrganizationMemberByUserID :one
SELECT
*
FROM
organization_members
WHERE
organization_id = $1
AND user_id = $2
LIMIT
1;
-- name: GetProjectByOrganizationAndName :one
SELECT
*
FROM
project
WHERE
organization_id = $1
AND name = $2
LIMIT
1;
-- name: GetProjectsByOrganizationIDs :many
SELECT
*
FROM
project
WHERE
organization_id = ANY(@ids :: text [ ]);
-- name: GetProjectHistoryByProjectID :many
SELECT
*
FROM
project_history
WHERE
project_id = $1;
-- name: InsertAPIKey :one
INSERT INTO
@@ -88,10 +143,89 @@ VALUES
) RETURNING *;
-- name: InsertOrganization :one
INSERT INTO organizations (id, name, description, created_at, updated_at) VALUES ($1, $2, $3, $4, $5) RETURNING *;
INSERT INTO
organizations (id, name, description, created_at, updated_at)
VALUES
($1, $2, $3, $4, $5) RETURNING *;
-- name: InsertOrganizationMember :one
INSERT INTO organization_members (organization_id, user_id, created_at, updated_at, roles) VALUES ($1, $2, $3, $4, $5) RETURNING *;
INSERT INTO
organization_members (
organization_id,
user_id,
created_at,
updated_at,
roles
)
VALUES
($1, $2, $3, $4, $5) RETURNING *;
-- name: InsertProject :one
INSERT INTO
project (
id,
created_at,
updated_at,
organization_id,
name,
provisioner
)
VALUES
($1, $2, $3, $4, $5, $6) RETURNING *;
-- name: InsertProjectHistory :one
INSERT INTO
project_history (
id,
project_id,
created_at,
updated_at,
name,
description,
storage_method,
storage_source,
import_job_id
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING *;
-- name: InsertProjectParameter :one
INSERT INTO
project_parameter (
id,
created_at,
project_history_id,
name,
description,
default_source,
allow_override_source,
default_destination,
allow_override_destination,
default_refresh,
redisplay_value,
validation_error,
validation_condition,
validation_type_system,
validation_value_type
)
VALUES
(
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8,
$9,
$10,
$11,
$12,
$13,
$14,
$15
) RETURNING *;
-- name: InsertUser :one
INSERT INTO
+378 -6
View File
@@ -5,8 +5,10 @@ package database
import (
"context"
"database/sql"
"time"
"github.com/google/uuid"
"github.com/lib/pq"
)
@@ -45,7 +47,14 @@ func (q *sqlQuerier) GetAPIKeyByID(ctx context.Context, id string) (APIKey, erro
}
const getOrganizationByName = `-- name: GetOrganizationByName :one
SELECT id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off FROM organizations WHERE name = $1 LIMIT 1
SELECT
id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off
FROM
organizations
WHERE
name = $1
LIMIT
1
`
func (q *sqlQuerier) GetOrganizationByName(ctx context.Context, name string) (Organization, error) {
@@ -66,10 +75,50 @@ func (q *sqlQuerier) GetOrganizationByName(ctx context.Context, name string) (Or
return i, err
}
const getOrganizationMemberByUserID = `-- name: GetOrganizationMemberByUserID :one
SELECT
organization_id, user_id, created_at, updated_at, roles
FROM
organization_members
WHERE
organization_id = $1
AND user_id = $2
LIMIT
1
`
type GetOrganizationMemberByUserIDParams struct {
OrganizationID string `db:"organization_id" json:"organization_id"`
UserID string `db:"user_id" json:"user_id"`
}
func (q *sqlQuerier) GetOrganizationMemberByUserID(ctx context.Context, arg GetOrganizationMemberByUserIDParams) (OrganizationMember, error) {
row := q.db.QueryRowContext(ctx, getOrganizationMemberByUserID, arg.OrganizationID, arg.UserID)
var i OrganizationMember
err := row.Scan(
&i.OrganizationID,
&i.UserID,
&i.CreatedAt,
&i.UpdatedAt,
pq.Array(&i.Roles),
)
return i, err
}
const getOrganizationsByUserID = `-- name: GetOrganizationsByUserID :many
SELECT id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off FROM organizations WHERE id = (
SELECT organization_id FROM organization_members WHERE user_id = $1
)
SELECT
id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off
FROM
organizations
WHERE
id = (
SELECT
organization_id
FROM
organization_members
WHERE
user_id = $1
)
`
func (q *sqlQuerier) GetOrganizationsByUserID(ctx context.Context, userID string) ([]Organization, error) {
@@ -106,6 +155,120 @@ func (q *sqlQuerier) GetOrganizationsByUserID(ctx context.Context, userID string
return items, nil
}
const getProjectByOrganizationAndName = `-- name: GetProjectByOrganizationAndName :one
SELECT
id, created_at, updated_at, organization_id, name, provisioner, active_version_id
FROM
project
WHERE
organization_id = $1
AND name = $2
LIMIT
1
`
type GetProjectByOrganizationAndNameParams struct {
OrganizationID string `db:"organization_id" json:"organization_id"`
Name string `db:"name" json:"name"`
}
func (q *sqlQuerier) GetProjectByOrganizationAndName(ctx context.Context, arg GetProjectByOrganizationAndNameParams) (Project, error) {
row := q.db.QueryRowContext(ctx, getProjectByOrganizationAndName, arg.OrganizationID, arg.Name)
var i Project
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.OrganizationID,
&i.Name,
&i.Provisioner,
&i.ActiveVersionID,
)
return i, err
}
const getProjectHistoryByProjectID = `-- name: GetProjectHistoryByProjectID :many
SELECT
id, project_id, created_at, updated_at, name, description, storage_method, storage_source, import_job_id
FROM
project_history
WHERE
project_id = $1
`
func (q *sqlQuerier) GetProjectHistoryByProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectHistory, error) {
rows, err := q.db.QueryContext(ctx, getProjectHistoryByProjectID, projectID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ProjectHistory
for rows.Next() {
var i ProjectHistory
if err := rows.Scan(
&i.ID,
&i.ProjectID,
&i.CreatedAt,
&i.UpdatedAt,
&i.Name,
&i.Description,
&i.StorageMethod,
&i.StorageSource,
&i.ImportJobID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getProjectsByOrganizationIDs = `-- name: GetProjectsByOrganizationIDs :many
SELECT
id, created_at, updated_at, organization_id, name, provisioner, active_version_id
FROM
project
WHERE
organization_id = ANY($1 :: text [ ])
`
func (q *sqlQuerier) GetProjectsByOrganizationIDs(ctx context.Context, ids []string) ([]Project, error) {
rows, err := q.db.QueryContext(ctx, getProjectsByOrganizationIDs, pq.Array(ids))
if err != nil {
return nil, err
}
defer rows.Close()
var items []Project
for rows.Next() {
var i Project
if err := rows.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.OrganizationID,
&i.Name,
&i.Provisioner,
&i.ActiveVersionID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getUserByEmailOrUsername = `-- name: GetUserByEmailOrUsername :one
SELECT
id, email, name, revoked, login_type, hashed_password, created_at, updated_at, temporary_password, avatar_hash, ssh_key_regenerated_at, username, dotfiles_git_uri, roles, status, relatime, gpg_key_regenerated_at, _decomissioned, shell
@@ -299,7 +462,10 @@ func (q *sqlQuerier) InsertAPIKey(ctx context.Context, arg InsertAPIKeyParams) (
}
const insertOrganization = `-- name: InsertOrganization :one
INSERT INTO organizations (id, name, description, created_at, updated_at) VALUES ($1, $2, $3, $4, $5) RETURNING id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off
INSERT INTO
organizations (id, name, description, created_at, updated_at)
VALUES
($1, $2, $3, $4, $5) RETURNING id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off
`
type InsertOrganizationParams struct {
@@ -335,7 +501,16 @@ func (q *sqlQuerier) InsertOrganization(ctx context.Context, arg InsertOrganizat
}
const insertOrganizationMember = `-- name: InsertOrganizationMember :one
INSERT INTO organization_members (organization_id, user_id, created_at, updated_at, roles) VALUES ($1, $2, $3, $4, $5) RETURNING organization_id, user_id, created_at, updated_at, roles
INSERT INTO
organization_members (
organization_id,
user_id,
created_at,
updated_at,
roles
)
VALUES
($1, $2, $3, $4, $5) RETURNING organization_id, user_id, created_at, updated_at, roles
`
type InsertOrganizationMemberParams struct {
@@ -365,6 +540,203 @@ func (q *sqlQuerier) InsertOrganizationMember(ctx context.Context, arg InsertOrg
return i, err
}
const insertProject = `-- name: InsertProject :one
INSERT INTO
project (
id,
created_at,
updated_at,
organization_id,
name,
provisioner
)
VALUES
($1, $2, $3, $4, $5, $6) RETURNING id, created_at, updated_at, organization_id, name, provisioner, active_version_id
`
type InsertProjectParams struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
OrganizationID string `db:"organization_id" json:"organization_id"`
Name string `db:"name" json:"name"`
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
}
func (q *sqlQuerier) InsertProject(ctx context.Context, arg InsertProjectParams) (Project, error) {
row := q.db.QueryRowContext(ctx, insertProject,
arg.ID,
arg.CreatedAt,
arg.UpdatedAt,
arg.OrganizationID,
arg.Name,
arg.Provisioner,
)
var i Project
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.OrganizationID,
&i.Name,
&i.Provisioner,
&i.ActiveVersionID,
)
return i, err
}
const insertProjectHistory = `-- name: InsertProjectHistory :one
INSERT INTO
project_history (
id,
project_id,
created_at,
updated_at,
name,
description,
storage_method,
storage_source,
import_job_id
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, project_id, created_at, updated_at, name, description, storage_method, storage_source, import_job_id
`
type InsertProjectHistoryParams struct {
ID uuid.UUID `db:"id" json:"id"`
ProjectID uuid.UUID `db:"project_id" json:"project_id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Name string `db:"name" json:"name"`
Description string `db:"description" json:"description"`
StorageMethod ProjectStorageMethod `db:"storage_method" json:"storage_method"`
StorageSource []byte `db:"storage_source" json:"storage_source"`
ImportJobID uuid.UUID `db:"import_job_id" json:"import_job_id"`
}
func (q *sqlQuerier) InsertProjectHistory(ctx context.Context, arg InsertProjectHistoryParams) (ProjectHistory, error) {
row := q.db.QueryRowContext(ctx, insertProjectHistory,
arg.ID,
arg.ProjectID,
arg.CreatedAt,
arg.UpdatedAt,
arg.Name,
arg.Description,
arg.StorageMethod,
arg.StorageSource,
arg.ImportJobID,
)
var i ProjectHistory
err := row.Scan(
&i.ID,
&i.ProjectID,
&i.CreatedAt,
&i.UpdatedAt,
&i.Name,
&i.Description,
&i.StorageMethod,
&i.StorageSource,
&i.ImportJobID,
)
return i, err
}
const insertProjectParameter = `-- name: InsertProjectParameter :one
INSERT INTO
project_parameter (
id,
created_at,
project_history_id,
name,
description,
default_source,
allow_override_source,
default_destination,
allow_override_destination,
default_refresh,
redisplay_value,
validation_error,
validation_condition,
validation_type_system,
validation_value_type
)
VALUES
(
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8,
$9,
$10,
$11,
$12,
$13,
$14,
$15
) RETURNING id, created_at, project_history_id, name, description, default_source, allow_override_source, default_destination, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type
`
type InsertProjectParameterParams struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
ProjectHistoryID uuid.UUID `db:"project_history_id" json:"project_history_id"`
Name string `db:"name" json:"name"`
Description string `db:"description" json:"description"`
DefaultSource sql.NullString `db:"default_source" json:"default_source"`
AllowOverrideSource bool `db:"allow_override_source" json:"allow_override_source"`
DefaultDestination sql.NullString `db:"default_destination" json:"default_destination"`
AllowOverrideDestination bool `db:"allow_override_destination" json:"allow_override_destination"`
DefaultRefresh string `db:"default_refresh" json:"default_refresh"`
RedisplayValue bool `db:"redisplay_value" json:"redisplay_value"`
ValidationError string `db:"validation_error" json:"validation_error"`
ValidationCondition string `db:"validation_condition" json:"validation_condition"`
ValidationTypeSystem ParameterTypeSystem `db:"validation_type_system" json:"validation_type_system"`
ValidationValueType string `db:"validation_value_type" json:"validation_value_type"`
}
func (q *sqlQuerier) InsertProjectParameter(ctx context.Context, arg InsertProjectParameterParams) (ProjectParameter, error) {
row := q.db.QueryRowContext(ctx, insertProjectParameter,
arg.ID,
arg.CreatedAt,
arg.ProjectHistoryID,
arg.Name,
arg.Description,
arg.DefaultSource,
arg.AllowOverrideSource,
arg.DefaultDestination,
arg.AllowOverrideDestination,
arg.DefaultRefresh,
arg.RedisplayValue,
arg.ValidationError,
arg.ValidationCondition,
arg.ValidationTypeSystem,
arg.ValidationValueType,
)
var i ProjectParameter
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.ProjectHistoryID,
&i.Name,
&i.Description,
&i.DefaultSource,
&i.AllowOverrideSource,
&i.DefaultDestination,
&i.AllowOverrideDestination,
&i.DefaultRefresh,
&i.RedisplayValue,
&i.ValidationError,
&i.ValidationCondition,
&i.ValidationTypeSystem,
&i.ValidationValueType,
)
return i, err
}
const insertUser = `-- name: InsertUser :one
INSERT INTO
users (
+1
View File
@@ -25,4 +25,5 @@ rename:
oidc_expiry: OIDCExpiry
oidc_id_token: OIDCIDToken
oidc_refresh_token: OIDCRefreshToken
parameter_type_system_hcl: ParameterTypeSystemHCL
userstatus: UserStatus