mirror of
https://github.com/coder/coder.git
synced 2025-07-21 01:28:49 +00:00
Migrations
Exclude system users from users.sql queries Signed-off-by: Danny Kopping <danny@coder.com>
This commit is contained in:
@ -2221,6 +2221,14 @@ func (q *querier) GetTemplateParameterInsights(ctx context.Context, arg database
|
||||
return q.db.GetTemplateParameterInsights(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplatePrebuildState(ctx context.Context, templateID uuid.UUID) ([]database.GetTemplatePrebuildStateRow, error) {
|
||||
// TODO: authz
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplatePrebuildState(ctx, templateID)
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplateUsageStats(ctx context.Context, arg database.GetTemplateUsageStatsParams) ([]database.TemplateUsageStat, error) {
|
||||
if err := q.authorizeTemplateInsights(ctx, arg.TemplateIDs); err != nil {
|
||||
return nil, err
|
||||
|
@ -5464,6 +5464,10 @@ func (q *FakeQuerier) GetTemplateParameterInsights(ctx context.Context, arg data
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetTemplatePrebuildState(ctx context.Context, templateID uuid.UUID) ([]database.GetTemplatePrebuildStateRow, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetTemplateUsageStats(_ context.Context, arg database.GetTemplateUsageStatsParams) ([]database.TemplateUsageStat, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
|
@ -1253,6 +1253,13 @@ func (m queryMetricsStore) GetTemplateParameterInsights(ctx context.Context, arg
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetTemplatePrebuildState(ctx context.Context, templateID uuid.UUID) ([]database.GetTemplatePrebuildStateRow, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetTemplatePrebuildState(ctx, templateID)
|
||||
m.queryLatencies.WithLabelValues("GetTemplatePrebuildState").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetTemplateUsageStats(ctx context.Context, arg database.GetTemplateUsageStatsParams) ([]database.TemplateUsageStat, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetTemplateUsageStats(ctx, arg)
|
||||
|
72
coderd/database/dump.sql
generated
72
coderd/database/dump.sql
generated
@ -769,6 +769,7 @@ CREATE TABLE users (
|
||||
github_com_user_id bigint,
|
||||
hashed_one_time_passcode bytea,
|
||||
one_time_passcode_expires_at timestamp with time zone,
|
||||
is_system boolean DEFAULT false,
|
||||
CONSTRAINT one_time_passcode_set CHECK ((((hashed_one_time_passcode IS NULL) AND (one_time_passcode_expires_at IS NULL)) OR ((hashed_one_time_passcode IS NOT NULL) AND (one_time_passcode_expires_at IS NOT NULL))))
|
||||
);
|
||||
|
||||
@ -784,6 +785,8 @@ COMMENT ON COLUMN users.hashed_one_time_passcode IS 'A hash of the one-time-pass
|
||||
|
||||
COMMENT ON COLUMN users.one_time_passcode_expires_at IS 'The time when the one-time-passcode expires.';
|
||||
|
||||
COMMENT ON COLUMN users.is_system IS 'Determines if a user is a system user, and therefore cannot login or perform normal actions';
|
||||
|
||||
CREATE VIEW group_members_expanded AS
|
||||
WITH all_members AS (
|
||||
SELECT group_members.user_id,
|
||||
@ -1780,6 +1783,52 @@ CREATE TABLE workspace_modules (
|
||||
created_at timestamp with time zone NOT NULL
|
||||
);
|
||||
|
||||
CREATE VIEW workspace_prebuild_builds AS
|
||||
SELECT workspace_builds.workspace_id
|
||||
FROM workspace_builds
|
||||
WHERE (workspace_builds.initiator_id = 'c42fdf75-3097-471c-8c33-fb52454d81c0'::uuid);
|
||||
|
||||
CREATE TABLE workspaces (
|
||||
id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
owner_id uuid NOT NULL,
|
||||
organization_id uuid NOT NULL,
|
||||
template_id uuid NOT NULL,
|
||||
deleted boolean DEFAULT false NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
autostart_schedule text,
|
||||
ttl bigint,
|
||||
last_used_at timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL,
|
||||
dormant_at timestamp with time zone,
|
||||
deleting_at timestamp with time zone,
|
||||
automatic_updates automatic_updates DEFAULT 'never'::automatic_updates NOT NULL,
|
||||
favorite boolean DEFAULT false NOT NULL,
|
||||
next_start_at timestamp with time zone
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN workspaces.favorite IS 'Favorite is true if the workspace owner has favorited the workspace.';
|
||||
|
||||
CREATE VIEW workspace_prebuilds AS
|
||||
SELECT workspaces.id,
|
||||
workspaces.created_at,
|
||||
workspaces.updated_at,
|
||||
workspaces.owner_id,
|
||||
workspaces.organization_id,
|
||||
workspaces.template_id,
|
||||
workspaces.deleted,
|
||||
workspaces.name,
|
||||
workspaces.autostart_schedule,
|
||||
workspaces.ttl,
|
||||
workspaces.last_used_at,
|
||||
workspaces.dormant_at,
|
||||
workspaces.deleting_at,
|
||||
workspaces.automatic_updates,
|
||||
workspaces.favorite,
|
||||
workspaces.next_start_at
|
||||
FROM workspaces
|
||||
WHERE (workspaces.owner_id = 'c42fdf75-3097-471c-8c33-fb52454d81c0'::uuid);
|
||||
|
||||
CREATE TABLE workspace_proxies (
|
||||
id uuid NOT NULL,
|
||||
name text NOT NULL,
|
||||
@ -1850,27 +1899,6 @@ CREATE TABLE workspace_resources (
|
||||
module_path text
|
||||
);
|
||||
|
||||
CREATE TABLE workspaces (
|
||||
id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
owner_id uuid NOT NULL,
|
||||
organization_id uuid NOT NULL,
|
||||
template_id uuid NOT NULL,
|
||||
deleted boolean DEFAULT false NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
autostart_schedule text,
|
||||
ttl bigint,
|
||||
last_used_at timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL,
|
||||
dormant_at timestamp with time zone,
|
||||
deleting_at timestamp with time zone,
|
||||
automatic_updates automatic_updates DEFAULT 'never'::automatic_updates NOT NULL,
|
||||
favorite boolean DEFAULT false NOT NULL,
|
||||
next_start_at timestamp with time zone
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN workspaces.favorite IS 'Favorite is true if the workspace owner has favorited the workspace.';
|
||||
|
||||
CREATE VIEW workspaces_expanded AS
|
||||
SELECT workspaces.id,
|
||||
workspaces.created_at,
|
||||
@ -2247,6 +2275,8 @@ COMMENT ON INDEX template_usage_stats_start_time_template_id_user_id_idx IS 'Ind
|
||||
|
||||
CREATE UNIQUE INDEX templates_organization_id_name_idx ON templates USING btree (organization_id, lower((name)::text)) WHERE (deleted = false);
|
||||
|
||||
CREATE INDEX user_is_system_idx ON users USING btree (is_system);
|
||||
|
||||
CREATE UNIQUE INDEX user_links_linked_id_login_type_idx ON user_links USING btree (linked_id, login_type) WHERE (linked_id <> ''::text);
|
||||
|
||||
CREATE UNIQUE INDEX users_email_lower_idx ON users USING btree (lower(email)) WHERE (deleted = false);
|
||||
|
4
coderd/database/migrations/000289_system_user.down.sql
Normal file
4
coderd/database/migrations/000289_system_user.down.sql
Normal file
@ -0,0 +1,4 @@
|
||||
ALTER TABLE users
|
||||
DROP COLUMN IF EXISTS is_system;
|
||||
|
||||
DROP INDEX IF EXISTS user_is_system_idx;
|
6
coderd/database/migrations/000289_system_user.up.sql
Normal file
6
coderd/database/migrations/000289_system_user.up.sql
Normal file
@ -0,0 +1,6 @@
|
||||
ALTER TABLE users
|
||||
ADD COLUMN is_system bool DEFAULT false;
|
||||
|
||||
CREATE INDEX user_is_system_idx ON users USING btree (is_system);
|
||||
|
||||
COMMENT ON COLUMN users.is_system IS 'Determines if a user is a system user, and therefore cannot login or perform normal actions';
|
7
coderd/database/migrations/000290_prebuilds.down.sql
Normal file
7
coderd/database/migrations/000290_prebuilds.down.sql
Normal file
@ -0,0 +1,7 @@
|
||||
-- Revert prebuild views
|
||||
DROP VIEW IF EXISTS workspace_prebuild_builds;
|
||||
DROP VIEW IF EXISTS workspace_prebuilds;
|
||||
|
||||
-- Revert user operations
|
||||
DELETE FROM user_status_changes WHERE user_id = 'c42fdf75-3097-471c-8c33-fb52454d81c0';
|
||||
DELETE FROM users WHERE id = 'c42fdf75-3097-471c-8c33-fb52454d81c0';
|
14
coderd/database/migrations/000290_prebuilds.up.sql
Normal file
14
coderd/database/migrations/000290_prebuilds.up.sql
Normal file
@ -0,0 +1,14 @@
|
||||
-- TODO: using "none" for login type produced this error: 'unsafe use of new value "none" of enum type login_type' -> not sure why
|
||||
INSERT INTO users (id, email, username, name, created_at, updated_at, status, rbac_roles, hashed_password, is_system)
|
||||
VALUES ('c42fdf75-3097-471c-8c33-fb52454d81c0', 'prebuilds@system', 'prebuilds', 'Prebuilds Owner', now(), now(),
|
||||
'active', '{}', 'none', true);
|
||||
|
||||
CREATE VIEW workspace_prebuilds AS
|
||||
SELECT *
|
||||
FROM workspaces
|
||||
WHERE owner_id = 'c42fdf75-3097-471c-8c33-fb52454d81c0';
|
||||
|
||||
CREATE VIEW workspace_prebuild_builds AS
|
||||
SELECT workspace_id
|
||||
FROM workspace_builds
|
||||
WHERE initiator_id = 'c42fdf75-3097-471c-8c33-fb52454d81c0';
|
@ -0,0 +1 @@
|
||||
CREATE TABLE
|
@ -422,6 +422,7 @@ func (q *sqlQuerier) GetAuthorizedUsers(ctx context.Context, arg GetUsersParams,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
&i.Count,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
|
@ -3035,6 +3035,8 @@ type User struct {
|
||||
HashedOneTimePasscode []byte `db:"hashed_one_time_passcode" json:"hashed_one_time_passcode"`
|
||||
// The time when the one-time-passcode expires.
|
||||
OneTimePasscodeExpiresAt sql.NullTime `db:"one_time_passcode_expires_at" json:"one_time_passcode_expires_at"`
|
||||
// Determines if a user is a system user, and therefore cannot login or perform normal actions
|
||||
IsSystem sql.NullBool `db:"is_system" json:"is_system"`
|
||||
}
|
||||
|
||||
// Tracks when users were deleted
|
||||
@ -3352,6 +3354,29 @@ type WorkspaceModule struct {
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
}
|
||||
|
||||
type WorkspacePrebuild 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"`
|
||||
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
||||
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
||||
TemplateID uuid.UUID `db:"template_id" json:"template_id"`
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
Name string `db:"name" json:"name"`
|
||||
AutostartSchedule sql.NullString `db:"autostart_schedule" json:"autostart_schedule"`
|
||||
Ttl sql.NullInt64 `db:"ttl" json:"ttl"`
|
||||
LastUsedAt time.Time `db:"last_used_at" json:"last_used_at"`
|
||||
DormantAt sql.NullTime `db:"dormant_at" json:"dormant_at"`
|
||||
DeletingAt sql.NullTime `db:"deleting_at" json:"deleting_at"`
|
||||
AutomaticUpdates AutomaticUpdates `db:"automatic_updates" json:"automatic_updates"`
|
||||
Favorite bool `db:"favorite" json:"favorite"`
|
||||
NextStartAt sql.NullTime `db:"next_start_at" json:"next_start_at"`
|
||||
}
|
||||
|
||||
type WorkspacePrebuildBuild struct {
|
||||
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
||||
}
|
||||
|
||||
type WorkspaceProxy struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
|
@ -265,6 +265,8 @@ type sqlcQuerier interface {
|
||||
// created in the timeframe and return the aggregate usage counts of parameter
|
||||
// values.
|
||||
GetTemplateParameterInsights(ctx context.Context, arg GetTemplateParameterInsightsParams) ([]GetTemplateParameterInsightsRow, error)
|
||||
// TODO: need to store the desired instances & autoscaling schedules in db; use desired value here
|
||||
GetTemplatePrebuildState(ctx context.Context, templateID uuid.UUID) ([]GetTemplatePrebuildStateRow, error)
|
||||
GetTemplateUsageStats(ctx context.Context, arg GetTemplateUsageStatsParams) ([]TemplateUsageStat, error)
|
||||
GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (TemplateVersion, error)
|
||||
GetTemplateVersionByJobID(ctx context.Context, jobID uuid.UUID) (TemplateVersion, error)
|
||||
|
@ -5395,6 +5395,75 @@ func (q *sqlQuerier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getTemplatePrebuildState = `-- name: GetTemplatePrebuildState :many
|
||||
WITH latest_workspace_builds AS (SELECT wb.id,
|
||||
wb.workspace_id,
|
||||
wbmax.template_id,
|
||||
wb.template_version_id
|
||||
FROM (SELECT tv.template_id,
|
||||
wbmax.workspace_id,
|
||||
MAX(wbmax.build_number) as max_build_number
|
||||
FROM workspace_builds wbmax
|
||||
JOIN template_versions tv ON (tv.id = wbmax.template_version_id)
|
||||
GROUP BY tv.template_id, wbmax.workspace_id) wbmax
|
||||
JOIN workspace_builds wb ON (
|
||||
wb.workspace_id = wbmax.workspace_id
|
||||
AND wb.build_number = wbmax.max_build_number
|
||||
))
|
||||
SELECT CAST(1 AS integer) AS desired,
|
||||
CAST(COUNT(wp.*) AS integer) AS actual,
|
||||
CAST(0 AS integer) AS extraneous, -- TODO: calculate this by subtracting actual from count not matching template version
|
||||
t.deleted,
|
||||
t.deprecated,
|
||||
tv.id AS template_version_id
|
||||
FROM latest_workspace_builds lwb
|
||||
JOIN template_versions tv ON lwb.template_version_id = tv.id
|
||||
JOIN templates t ON t.id = lwb.template_id
|
||||
LEFT JOIN workspace_prebuilds wp ON wp.id = lwb.workspace_id
|
||||
WHERE t.id = $1::uuid
|
||||
GROUP BY t.id, t.deleted, t.deprecated, tv.id
|
||||
`
|
||||
|
||||
type GetTemplatePrebuildStateRow struct {
|
||||
Desired int32 `db:"desired" json:"desired"`
|
||||
Actual int32 `db:"actual" json:"actual"`
|
||||
Extraneous int32 `db:"extraneous" json:"extraneous"`
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
Deprecated string `db:"deprecated" json:"deprecated"`
|
||||
TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
|
||||
}
|
||||
|
||||
// TODO: need to store the desired instances & autoscaling schedules in db; use desired value here
|
||||
func (q *sqlQuerier) GetTemplatePrebuildState(ctx context.Context, templateID uuid.UUID) ([]GetTemplatePrebuildStateRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getTemplatePrebuildState, templateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetTemplatePrebuildStateRow
|
||||
for rows.Next() {
|
||||
var i GetTemplatePrebuildStateRow
|
||||
if err := rows.Scan(
|
||||
&i.Desired,
|
||||
&i.Actual,
|
||||
&i.Extraneous,
|
||||
&i.Deleted,
|
||||
&i.Deprecated,
|
||||
&i.TemplateVersionID,
|
||||
); 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 getPresetByWorkspaceBuildID = `-- name: GetPresetByWorkspaceBuildID :one
|
||||
SELECT
|
||||
template_version_presets.id, template_version_presets.template_version_id, template_version_presets.name, template_version_presets.created_at
|
||||
@ -10863,6 +10932,7 @@ func (q *sqlQuerier) UpdateUserLinkedID(ctx context.Context, arg UpdateUserLinke
|
||||
|
||||
const allUserIDs = `-- name: AllUserIDs :many
|
||||
SELECT DISTINCT id FROM USERS
|
||||
WHERE is_system = false
|
||||
`
|
||||
|
||||
// AllUserIDs returns all UserIDs regardless of user status or deletion.
|
||||
@ -10896,6 +10966,7 @@ FROM
|
||||
users
|
||||
WHERE
|
||||
status = 'active'::user_status AND deleted = false
|
||||
AND is_system = false
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetActiveUserCount(ctx context.Context) (int64, error) {
|
||||
@ -10972,7 +11043,7 @@ func (q *sqlQuerier) GetAuthorizationUserRoles(ctx context.Context, userID uuid.
|
||||
|
||||
const getUserByEmailOrUsername = `-- name: GetUserByEmailOrUsername :one
|
||||
SELECT
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
FROM
|
||||
users
|
||||
WHERE
|
||||
@ -11009,13 +11080,14 @@ func (q *sqlQuerier) GetUserByEmailOrUsername(ctx context.Context, arg GetUserBy
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserByID = `-- name: GetUserByID :one
|
||||
SELECT
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
FROM
|
||||
users
|
||||
WHERE
|
||||
@ -11046,6 +11118,7 @@ func (q *sqlQuerier) GetUserByID(ctx context.Context, id uuid.UUID) (User, error
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11057,6 +11130,7 @@ FROM
|
||||
users
|
||||
WHERE
|
||||
deleted = false
|
||||
AND is_system = false
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetUserCount(ctx context.Context) (int64, error) {
|
||||
@ -11068,11 +11142,12 @@ func (q *sqlQuerier) GetUserCount(ctx context.Context) (int64, error) {
|
||||
|
||||
const getUsers = `-- name: GetUsers :many
|
||||
SELECT
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, COUNT(*) OVER() AS count
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system, COUNT(*) OVER() AS count
|
||||
FROM
|
||||
users
|
||||
WHERE
|
||||
users.deleted = false
|
||||
AND is_system = false
|
||||
AND CASE
|
||||
-- This allows using the last element on a page as effectively a cursor.
|
||||
-- This is an important option for scripts that need to paginate without
|
||||
@ -11183,6 +11258,7 @@ type GetUsersRow struct {
|
||||
GithubComUserID sql.NullInt64 `db:"github_com_user_id" json:"github_com_user_id"`
|
||||
HashedOneTimePasscode []byte `db:"hashed_one_time_passcode" json:"hashed_one_time_passcode"`
|
||||
OneTimePasscodeExpiresAt sql.NullTime `db:"one_time_passcode_expires_at" json:"one_time_passcode_expires_at"`
|
||||
IsSystem sql.NullBool `db:"is_system" json:"is_system"`
|
||||
Count int64 `db:"count" json:"count"`
|
||||
}
|
||||
|
||||
@ -11226,6 +11302,7 @@ func (q *sqlQuerier) GetUsers(ctx context.Context, arg GetUsersParams) ([]GetUse
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
&i.Count,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
@ -11242,7 +11319,7 @@ func (q *sqlQuerier) GetUsers(ctx context.Context, arg GetUsersParams) ([]GetUse
|
||||
}
|
||||
|
||||
const getUsersByIDs = `-- name: GetUsersByIDs :many
|
||||
SELECT id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at FROM users WHERE id = ANY($1 :: uuid [ ])
|
||||
SELECT id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system FROM users WHERE id = ANY($1 :: uuid [ ])
|
||||
`
|
||||
|
||||
// This shouldn't check for deleted, because it's frequently used
|
||||
@ -11276,6 +11353,7 @@ func (q *sqlQuerier) GetUsersByIDs(ctx context.Context, ids []uuid.UUID) ([]User
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -11309,7 +11387,7 @@ VALUES
|
||||
-- if the status passed in is empty, fallback to dormant, which is what
|
||||
-- we were doing before.
|
||||
COALESCE(NULLIF($10::text, '')::user_status, 'dormant'::user_status)
|
||||
) RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
) RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
`
|
||||
|
||||
type InsertUserParams struct {
|
||||
@ -11358,6 +11436,7 @@ func (q *sqlQuerier) InsertUser(ctx context.Context, arg InsertUserParams) (User
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11371,6 +11450,7 @@ SET
|
||||
WHERE
|
||||
last_seen_at < $2 :: timestamp
|
||||
AND status = 'active'::user_status
|
||||
AND is_system = false
|
||||
RETURNING id, email, username, last_seen_at
|
||||
`
|
||||
|
||||
@ -11422,7 +11502,7 @@ SET
|
||||
updated_at = $3
|
||||
WHERE
|
||||
id = $1
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
`
|
||||
|
||||
type UpdateUserAppearanceSettingsParams struct {
|
||||
@ -11453,6 +11533,7 @@ func (q *sqlQuerier) UpdateUserAppearanceSettings(ctx context.Context, arg Updat
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11539,7 +11620,7 @@ SET
|
||||
last_seen_at = $2,
|
||||
updated_at = $3
|
||||
WHERE
|
||||
id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
`
|
||||
|
||||
type UpdateUserLastSeenAtParams struct {
|
||||
@ -11570,6 +11651,7 @@ func (q *sqlQuerier) UpdateUserLastSeenAt(ctx context.Context, arg UpdateUserLas
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11587,7 +11669,7 @@ SET
|
||||
'':: bytea
|
||||
END
|
||||
WHERE
|
||||
id = $2 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id = $2 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
`
|
||||
|
||||
type UpdateUserLoginTypeParams struct {
|
||||
@ -11617,6 +11699,7 @@ func (q *sqlQuerier) UpdateUserLoginType(ctx context.Context, arg UpdateUserLogi
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11632,7 +11715,7 @@ SET
|
||||
name = $6
|
||||
WHERE
|
||||
id = $1
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
`
|
||||
|
||||
type UpdateUserProfileParams struct {
|
||||
@ -11673,6 +11756,7 @@ func (q *sqlQuerier) UpdateUserProfile(ctx context.Context, arg UpdateUserProfil
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11684,7 +11768,7 @@ SET
|
||||
quiet_hours_schedule = $2
|
||||
WHERE
|
||||
id = $1
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
`
|
||||
|
||||
type UpdateUserQuietHoursScheduleParams struct {
|
||||
@ -11714,6 +11798,7 @@ func (q *sqlQuerier) UpdateUserQuietHoursSchedule(ctx context.Context, arg Updat
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11726,7 +11811,7 @@ SET
|
||||
rbac_roles = ARRAY(SELECT DISTINCT UNNEST($1 :: text[]))
|
||||
WHERE
|
||||
id = $2
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
`
|
||||
|
||||
type UpdateUserRolesParams struct {
|
||||
@ -11756,6 +11841,7 @@ func (q *sqlQuerier) UpdateUserRoles(ctx context.Context, arg UpdateUserRolesPar
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11767,7 +11853,7 @@ SET
|
||||
status = $2,
|
||||
updated_at = $3
|
||||
WHERE
|
||||
id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, is_system
|
||||
`
|
||||
|
||||
type UpdateUserStatusParams struct {
|
||||
@ -11798,6 +11884,7 @@ func (q *sqlQuerier) UpdateUserStatus(ctx context.Context, arg UpdateUserStatusP
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
&i.IsSystem,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
28
coderd/database/queries/prebuilds.sql
Normal file
28
coderd/database/queries/prebuilds.sql
Normal file
@ -0,0 +1,28 @@
|
||||
-- name: GetTemplatePrebuildState :many
|
||||
WITH latest_workspace_builds AS (SELECT wb.id,
|
||||
wb.workspace_id,
|
||||
wbmax.template_id,
|
||||
wb.template_version_id
|
||||
FROM (SELECT tv.template_id,
|
||||
wbmax.workspace_id,
|
||||
MAX(wbmax.build_number) as max_build_number
|
||||
FROM workspace_builds wbmax
|
||||
JOIN template_versions tv ON (tv.id = wbmax.template_version_id)
|
||||
GROUP BY tv.template_id, wbmax.workspace_id) wbmax
|
||||
JOIN workspace_builds wb ON (
|
||||
wb.workspace_id = wbmax.workspace_id
|
||||
AND wb.build_number = wbmax.max_build_number
|
||||
))
|
||||
-- TODO: need to store the desired instances & autoscaling schedules in db; use desired value here
|
||||
SELECT CAST(1 AS integer) AS desired,
|
||||
CAST(COUNT(wp.*) AS integer) AS actual,
|
||||
CAST(0 AS integer) AS extraneous, -- TODO: calculate this by subtracting actual from count not matching template version
|
||||
t.deleted,
|
||||
t.deprecated,
|
||||
tv.id AS template_version_id
|
||||
FROM latest_workspace_builds lwb
|
||||
JOIN template_versions tv ON lwb.template_version_id = tv.id
|
||||
JOIN templates t ON t.id = lwb.template_id
|
||||
LEFT JOIN workspace_prebuilds wp ON wp.id = lwb.workspace_id
|
||||
WHERE t.id = @template_id::uuid
|
||||
GROUP BY t.id, t.deleted, t.deprecated, tv.id;
|
@ -46,7 +46,8 @@ SELECT
|
||||
FROM
|
||||
users
|
||||
WHERE
|
||||
deleted = false;
|
||||
deleted = false
|
||||
AND is_system = false;
|
||||
|
||||
-- name: GetActiveUserCount :one
|
||||
SELECT
|
||||
@ -54,7 +55,8 @@ SELECT
|
||||
FROM
|
||||
users
|
||||
WHERE
|
||||
status = 'active'::user_status AND deleted = false;
|
||||
status = 'active'::user_status AND deleted = false
|
||||
AND is_system = false;
|
||||
|
||||
-- name: InsertUser :one
|
||||
INSERT INTO
|
||||
@ -144,6 +146,7 @@ FROM
|
||||
users
|
||||
WHERE
|
||||
users.deleted = false
|
||||
AND is_system = false
|
||||
AND CASE
|
||||
-- This allows using the last element on a page as effectively a cursor.
|
||||
-- This is an important option for scripts that need to paginate without
|
||||
@ -302,11 +305,13 @@ SET
|
||||
WHERE
|
||||
last_seen_at < @last_seen_after :: timestamp
|
||||
AND status = 'active'::user_status
|
||||
AND is_system = false
|
||||
RETURNING id, email, username, last_seen_at;
|
||||
|
||||
-- AllUserIDs returns all UserIDs regardless of user status or deletion.
|
||||
-- name: AllUserIDs :many
|
||||
SELECT DISTINCT id FROM USERS;
|
||||
SELECT DISTINCT id FROM USERS
|
||||
WHERE is_system = false;
|
||||
|
||||
-- name: UpdateUserHashedOneTimePasscode :exec
|
||||
UPDATE
|
||||
|
@ -28,7 +28,7 @@ We track the following resources:
|
||||
| RoleSyncSettings<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>field</td><td>true</td></tr><tr><td>mapping</td><td>true</td></tr></tbody></table> |
|
||||
| Template<br><i>write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>active_version_id</td><td>true</td></tr><tr><td>activity_bump</td><td>true</td></tr><tr><td>allow_user_autostart</td><td>true</td></tr><tr><td>allow_user_autostop</td><td>true</td></tr><tr><td>allow_user_cancel_workspace_jobs</td><td>true</td></tr><tr><td>autostart_block_days_of_week</td><td>true</td></tr><tr><td>autostop_requirement_days_of_week</td><td>true</td></tr><tr><td>autostop_requirement_weeks</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>created_by</td><td>true</td></tr><tr><td>created_by_avatar_url</td><td>false</td></tr><tr><td>created_by_username</td><td>false</td></tr><tr><td>default_ttl</td><td>true</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>deprecated</td><td>true</td></tr><tr><td>description</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>failure_ttl</td><td>true</td></tr><tr><td>group_acl</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>max_port_sharing_level</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_display_name</td><td>false</td></tr><tr><td>organization_icon</td><td>false</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>organization_name</td><td>false</td></tr><tr><td>provisioner</td><td>true</td></tr><tr><td>require_active_version</td><td>true</td></tr><tr><td>time_til_dormant</td><td>true</td></tr><tr><td>time_til_dormant_autodelete</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_acl</td><td>true</td></tr></tbody></table> |
|
||||
| TemplateVersion<br><i>create, write</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>archived</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>created_by</td><td>true</td></tr><tr><td>created_by_avatar_url</td><td>false</td></tr><tr><td>created_by_username</td><td>false</td></tr><tr><td>external_auth_providers</td><td>false</td></tr><tr><td>id</td><td>true</td></tr><tr><td>job_id</td><td>false</td></tr><tr><td>message</td><td>false</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>readme</td><td>true</td></tr><tr><td>source_example_id</td><td>false</td></tr><tr><td>template_id</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr></tbody></table> |
|
||||
| User<br><i>create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>avatar_url</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>true</td></tr><tr><td>email</td><td>true</td></tr><tr><td>github_com_user_id</td><td>false</td></tr><tr><td>hashed_one_time_passcode</td><td>false</td></tr><tr><td>hashed_password</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>last_seen_at</td><td>false</td></tr><tr><td>login_type</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>one_time_passcode_expires_at</td><td>true</td></tr><tr><td>quiet_hours_schedule</td><td>true</td></tr><tr><td>rbac_roles</td><td>true</td></tr><tr><td>status</td><td>true</td></tr><tr><td>theme_preference</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>username</td><td>true</td></tr></tbody></table> |
|
||||
| User<br><i>create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>avatar_url</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>true</td></tr><tr><td>email</td><td>true</td></tr><tr><td>github_com_user_id</td><td>false</td></tr><tr><td>hashed_one_time_passcode</td><td>false</td></tr><tr><td>hashed_password</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>is_system</td><td>true</td></tr><tr><td>last_seen_at</td><td>false</td></tr><tr><td>login_type</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>one_time_passcode_expires_at</td><td>true</td></tr><tr><td>quiet_hours_schedule</td><td>true</td></tr><tr><td>rbac_roles</td><td>true</td></tr><tr><td>status</td><td>true</td></tr><tr><td>theme_preference</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>username</td><td>true</td></tr></tbody></table> |
|
||||
| WorkspaceBuild<br><i>start, stop</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>build_number</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>daily_cost</td><td>false</td></tr><tr><td>deadline</td><td>false</td></tr><tr><td>id</td><td>false</td></tr><tr><td>initiator_by_avatar_url</td><td>false</td></tr><tr><td>initiator_by_username</td><td>false</td></tr><tr><td>initiator_id</td><td>false</td></tr><tr><td>job_id</td><td>false</td></tr><tr><td>max_deadline</td><td>false</td></tr><tr><td>provisioner_state</td><td>false</td></tr><tr><td>reason</td><td>false</td></tr><tr><td>template_version_id</td><td>true</td></tr><tr><td>template_version_preset_id</td><td>false</td></tr><tr><td>transition</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>workspace_id</td><td>false</td></tr></tbody></table> |
|
||||
| WorkspaceProxy<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>true</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>derp_enabled</td><td>true</td></tr><tr><td>derp_only</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>region_id</td><td>true</td></tr><tr><td>token_hashed_secret</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>url</td><td>true</td></tr><tr><td>version</td><td>true</td></tr><tr><td>wildcard_hostname</td><td>true</td></tr></tbody></table> |
|
||||
| WorkspaceTable<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>automatic_updates</td><td>true</td></tr><tr><td>autostart_schedule</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>deleting_at</td><td>true</td></tr><tr><td>dormant_at</td><td>true</td></tr><tr><td>favorite</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>last_used_at</td><td>false</td></tr><tr><td>name</td><td>true</td></tr><tr><td>next_start_at</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>owner_id</td><td>true</td></tr><tr><td>template_id</td><td>true</td></tr><tr><td>ttl</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr></tbody></table> |
|
||||
|
@ -150,6 +150,7 @@ var auditableResourcesTypes = map[any]map[string]Action{
|
||||
"github_com_user_id": ActionIgnore,
|
||||
"hashed_one_time_passcode": ActionIgnore,
|
||||
"one_time_passcode_expires_at": ActionTrack,
|
||||
"is_system": ActionTrack, // Should never change, but track it anyway.
|
||||
},
|
||||
&database.WorkspaceTable{}: {
|
||||
"id": ActionTrack,
|
||||
|
Reference in New Issue
Block a user