mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
* feat: Add connection_timeout and troubleshooting_url to agent This commit adds the connection timeout and troubleshooting url fields to coder agents. If an initial connection cannot be established within connection timeout seconds, then the agent status will be marked as `"timeout"`. The troubleshooting URL will be present, if configured in the Terraform template, it can be presented to the user when the agent state is either `"timeout"` or `"disconnected"`. Fixes #4678
6580 lines
169 KiB
Go
6580 lines
169 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.13.0
|
|
|
|
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/lib/pq"
|
|
"github.com/tabbed/pqtype"
|
|
)
|
|
|
|
const deleteOldAgentStats = `-- name: DeleteOldAgentStats :exec
|
|
DELETE FROM AGENT_STATS WHERE created_at < now() - interval '30 days'
|
|
`
|
|
|
|
func (q *sqlQuerier) DeleteOldAgentStats(ctx context.Context) error {
|
|
_, err := q.db.ExecContext(ctx, deleteOldAgentStats)
|
|
return err
|
|
}
|
|
|
|
const getLatestAgentStat = `-- name: GetLatestAgentStat :one
|
|
SELECT id, created_at, user_id, agent_id, workspace_id, template_id, payload FROM agent_stats WHERE agent_id = $1 ORDER BY created_at DESC LIMIT 1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetLatestAgentStat(ctx context.Context, agentID uuid.UUID) (AgentStat, error) {
|
|
row := q.db.QueryRowContext(ctx, getLatestAgentStat, agentID)
|
|
var i AgentStat
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UserID,
|
|
&i.AgentID,
|
|
&i.WorkspaceID,
|
|
&i.TemplateID,
|
|
&i.Payload,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getTemplateDAUs = `-- name: GetTemplateDAUs :many
|
|
select
|
|
(created_at at TIME ZONE 'UTC')::date as date,
|
|
user_id
|
|
from
|
|
agent_stats
|
|
where template_id = $1
|
|
group by
|
|
date, user_id
|
|
order by
|
|
date asc
|
|
`
|
|
|
|
type GetTemplateDAUsRow struct {
|
|
Date time.Time `db:"date" json:"date"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetTemplateDAUs(ctx context.Context, templateID uuid.UUID) ([]GetTemplateDAUsRow, error) {
|
|
rows, err := q.db.QueryContext(ctx, getTemplateDAUs, templateID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetTemplateDAUsRow
|
|
for rows.Next() {
|
|
var i GetTemplateDAUsRow
|
|
if err := rows.Scan(&i.Date, &i.UserID); 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 insertAgentStat = `-- name: InsertAgentStat :one
|
|
INSERT INTO
|
|
agent_stats (
|
|
id,
|
|
created_at,
|
|
user_id,
|
|
workspace_id,
|
|
template_id,
|
|
agent_id,
|
|
payload
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7) RETURNING id, created_at, user_id, agent_id, workspace_id, template_id, payload
|
|
`
|
|
|
|
type InsertAgentStatParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
|
TemplateID uuid.UUID `db:"template_id" json:"template_id"`
|
|
AgentID uuid.UUID `db:"agent_id" json:"agent_id"`
|
|
Payload json.RawMessage `db:"payload" json:"payload"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertAgentStat(ctx context.Context, arg InsertAgentStatParams) (AgentStat, error) {
|
|
row := q.db.QueryRowContext(ctx, insertAgentStat,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.UserID,
|
|
arg.WorkspaceID,
|
|
arg.TemplateID,
|
|
arg.AgentID,
|
|
arg.Payload,
|
|
)
|
|
var i AgentStat
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UserID,
|
|
&i.AgentID,
|
|
&i.WorkspaceID,
|
|
&i.TemplateID,
|
|
&i.Payload,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteAPIKeyByID = `-- name: DeleteAPIKeyByID :exec
|
|
DELETE
|
|
FROM
|
|
api_keys
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) DeleteAPIKeyByID(ctx context.Context, id string) error {
|
|
_, err := q.db.ExecContext(ctx, deleteAPIKeyByID, id)
|
|
return err
|
|
}
|
|
|
|
const deleteAPIKeysByUserID = `-- name: DeleteAPIKeysByUserID :exec
|
|
DELETE FROM
|
|
api_keys
|
|
WHERE
|
|
user_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) DeleteAPIKeysByUserID(ctx context.Context, userID uuid.UUID) error {
|
|
_, err := q.db.ExecContext(ctx, deleteAPIKeysByUserID, userID)
|
|
return err
|
|
}
|
|
|
|
const getAPIKeyByID = `-- name: GetAPIKeyByID :one
|
|
SELECT
|
|
id, hashed_secret, user_id, last_used, expires_at, created_at, updated_at, login_type, lifetime_seconds, ip_address, scope
|
|
FROM
|
|
api_keys
|
|
WHERE
|
|
id = $1
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetAPIKeyByID(ctx context.Context, id string) (APIKey, error) {
|
|
row := q.db.QueryRowContext(ctx, getAPIKeyByID, id)
|
|
var i APIKey
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.HashedSecret,
|
|
&i.UserID,
|
|
&i.LastUsed,
|
|
&i.ExpiresAt,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.LoginType,
|
|
&i.LifetimeSeconds,
|
|
&i.IPAddress,
|
|
&i.Scope,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getAPIKeysByLoginType = `-- name: GetAPIKeysByLoginType :many
|
|
SELECT id, hashed_secret, user_id, last_used, expires_at, created_at, updated_at, login_type, lifetime_seconds, ip_address, scope FROM api_keys WHERE login_type = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetAPIKeysByLoginType(ctx context.Context, loginType LoginType) ([]APIKey, error) {
|
|
rows, err := q.db.QueryContext(ctx, getAPIKeysByLoginType, loginType)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []APIKey
|
|
for rows.Next() {
|
|
var i APIKey
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.HashedSecret,
|
|
&i.UserID,
|
|
&i.LastUsed,
|
|
&i.ExpiresAt,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.LoginType,
|
|
&i.LifetimeSeconds,
|
|
&i.IPAddress,
|
|
&i.Scope,
|
|
); 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 getAPIKeysLastUsedAfter = `-- name: GetAPIKeysLastUsedAfter :many
|
|
SELECT id, hashed_secret, user_id, last_used, expires_at, created_at, updated_at, login_type, lifetime_seconds, ip_address, scope FROM api_keys WHERE last_used > $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetAPIKeysLastUsedAfter(ctx context.Context, lastUsed time.Time) ([]APIKey, error) {
|
|
rows, err := q.db.QueryContext(ctx, getAPIKeysLastUsedAfter, lastUsed)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []APIKey
|
|
for rows.Next() {
|
|
var i APIKey
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.HashedSecret,
|
|
&i.UserID,
|
|
&i.LastUsed,
|
|
&i.ExpiresAt,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.LoginType,
|
|
&i.LifetimeSeconds,
|
|
&i.IPAddress,
|
|
&i.Scope,
|
|
); 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 insertAPIKey = `-- name: InsertAPIKey :one
|
|
INSERT INTO
|
|
api_keys (
|
|
id,
|
|
lifetime_seconds,
|
|
hashed_secret,
|
|
ip_address,
|
|
user_id,
|
|
last_used,
|
|
expires_at,
|
|
created_at,
|
|
updated_at,
|
|
login_type,
|
|
scope
|
|
)
|
|
VALUES
|
|
($1,
|
|
-- If the lifetime is set to 0, default to 24hrs
|
|
CASE $2::bigint
|
|
WHEN 0 THEN 86400
|
|
ELSE $2::bigint
|
|
END
|
|
, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, hashed_secret, user_id, last_used, expires_at, created_at, updated_at, login_type, lifetime_seconds, ip_address, scope
|
|
`
|
|
|
|
type InsertAPIKeyParams struct {
|
|
ID string `db:"id" json:"id"`
|
|
LifetimeSeconds int64 `db:"lifetime_seconds" json:"lifetime_seconds"`
|
|
HashedSecret []byte `db:"hashed_secret" json:"hashed_secret"`
|
|
IPAddress pqtype.Inet `db:"ip_address" json:"ip_address"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
LastUsed time.Time `db:"last_used" json:"last_used"`
|
|
ExpiresAt time.Time `db:"expires_at" json:"expires_at"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
LoginType LoginType `db:"login_type" json:"login_type"`
|
|
Scope APIKeyScope `db:"scope" json:"scope"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertAPIKey(ctx context.Context, arg InsertAPIKeyParams) (APIKey, error) {
|
|
row := q.db.QueryRowContext(ctx, insertAPIKey,
|
|
arg.ID,
|
|
arg.LifetimeSeconds,
|
|
arg.HashedSecret,
|
|
arg.IPAddress,
|
|
arg.UserID,
|
|
arg.LastUsed,
|
|
arg.ExpiresAt,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.LoginType,
|
|
arg.Scope,
|
|
)
|
|
var i APIKey
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.HashedSecret,
|
|
&i.UserID,
|
|
&i.LastUsed,
|
|
&i.ExpiresAt,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.LoginType,
|
|
&i.LifetimeSeconds,
|
|
&i.IPAddress,
|
|
&i.Scope,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateAPIKeyByID = `-- name: UpdateAPIKeyByID :exec
|
|
UPDATE
|
|
api_keys
|
|
SET
|
|
last_used = $2,
|
|
expires_at = $3,
|
|
ip_address = $4
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateAPIKeyByIDParams struct {
|
|
ID string `db:"id" json:"id"`
|
|
LastUsed time.Time `db:"last_used" json:"last_used"`
|
|
ExpiresAt time.Time `db:"expires_at" json:"expires_at"`
|
|
IPAddress pqtype.Inet `db:"ip_address" json:"ip_address"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateAPIKeyByID(ctx context.Context, arg UpdateAPIKeyByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateAPIKeyByID,
|
|
arg.ID,
|
|
arg.LastUsed,
|
|
arg.ExpiresAt,
|
|
arg.IPAddress,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const getAuditLogCount = `-- name: GetAuditLogCount :one
|
|
SELECT
|
|
COUNT(*) as count
|
|
FROM
|
|
audit_logs
|
|
WHERE
|
|
-- Filter resource_type
|
|
CASE
|
|
WHEN $1 :: text != '' THEN
|
|
resource_type = $1 :: resource_type
|
|
ELSE true
|
|
END
|
|
-- Filter resource_id
|
|
AND CASE
|
|
WHEN $2 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
|
|
resource_id = $2
|
|
ELSE true
|
|
END
|
|
-- Filter by resource_target
|
|
AND CASE
|
|
WHEN $3 :: text != '' THEN
|
|
resource_target = $3
|
|
ELSE true
|
|
END
|
|
-- Filter action
|
|
AND CASE
|
|
WHEN $4 :: text != '' THEN
|
|
action = $4 :: audit_action
|
|
ELSE true
|
|
END
|
|
-- Filter by username
|
|
AND CASE
|
|
WHEN $5 :: text != '' THEN
|
|
user_id = (SELECT id from users WHERE users.username = $5 )
|
|
ELSE true
|
|
END
|
|
-- Filter by user_email
|
|
AND CASE
|
|
WHEN $6 :: text != '' THEN
|
|
user_id = (SELECT id from users WHERE users.email = $6 )
|
|
ELSE true
|
|
END
|
|
-- Filter by date_from
|
|
AND CASE
|
|
WHEN $7 :: timestamp with time zone != '0001-01-01 00:00:00' THEN
|
|
"time" >= $7
|
|
ELSE true
|
|
END
|
|
-- Filter by date_to
|
|
AND CASE
|
|
WHEN $8 :: timestamp with time zone != '0001-01-01 00:00:00' THEN
|
|
"time" <= $8
|
|
ELSE true
|
|
END
|
|
`
|
|
|
|
type GetAuditLogCountParams struct {
|
|
ResourceType string `db:"resource_type" json:"resource_type"`
|
|
ResourceID uuid.UUID `db:"resource_id" json:"resource_id"`
|
|
ResourceTarget string `db:"resource_target" json:"resource_target"`
|
|
Action string `db:"action" json:"action"`
|
|
Username string `db:"username" json:"username"`
|
|
Email string `db:"email" json:"email"`
|
|
DateFrom time.Time `db:"date_from" json:"date_from"`
|
|
DateTo time.Time `db:"date_to" json:"date_to"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetAuditLogCount(ctx context.Context, arg GetAuditLogCountParams) (int64, error) {
|
|
row := q.db.QueryRowContext(ctx, getAuditLogCount,
|
|
arg.ResourceType,
|
|
arg.ResourceID,
|
|
arg.ResourceTarget,
|
|
arg.Action,
|
|
arg.Username,
|
|
arg.Email,
|
|
arg.DateFrom,
|
|
arg.DateTo,
|
|
)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const getAuditLogsOffset = `-- name: GetAuditLogsOffset :many
|
|
SELECT
|
|
audit_logs.id, audit_logs.time, audit_logs.user_id, audit_logs.organization_id, audit_logs.ip, audit_logs.user_agent, audit_logs.resource_type, audit_logs.resource_id, audit_logs.resource_target, audit_logs.action, audit_logs.diff, audit_logs.status_code, audit_logs.additional_fields, audit_logs.request_id, audit_logs.resource_icon,
|
|
users.username AS user_username,
|
|
users.email AS user_email,
|
|
users.created_at AS user_created_at,
|
|
users.status AS user_status,
|
|
users.rbac_roles AS user_roles,
|
|
users.avatar_url AS user_avatar_url
|
|
FROM
|
|
audit_logs
|
|
LEFT JOIN
|
|
users ON audit_logs.user_id = users.id
|
|
WHERE
|
|
-- Filter resource_type
|
|
CASE
|
|
WHEN $3 :: text != '' THEN
|
|
resource_type = $3 :: resource_type
|
|
ELSE true
|
|
END
|
|
-- Filter resource_id
|
|
AND CASE
|
|
WHEN $4 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
|
|
resource_id = $4
|
|
ELSE true
|
|
END
|
|
-- Filter by resource_target
|
|
AND CASE
|
|
WHEN $5 :: text != '' THEN
|
|
resource_target = $5
|
|
ELSE true
|
|
END
|
|
-- Filter action
|
|
AND CASE
|
|
WHEN $6 :: text != '' THEN
|
|
action = $6 :: audit_action
|
|
ELSE true
|
|
END
|
|
-- Filter by username
|
|
AND CASE
|
|
WHEN $7 :: text != '' THEN
|
|
users.username = $7
|
|
ELSE true
|
|
END
|
|
-- Filter by user_email
|
|
AND CASE
|
|
WHEN $8 :: text != '' THEN
|
|
users.email = $8
|
|
ELSE true
|
|
END
|
|
-- Filter by date_from
|
|
AND CASE
|
|
WHEN $9 :: timestamp with time zone != '0001-01-01 00:00:00' THEN
|
|
"time" >= $9
|
|
ELSE true
|
|
END
|
|
-- Filter by date_to
|
|
AND CASE
|
|
WHEN $10 :: timestamp with time zone != '0001-01-01 00:00:00' THEN
|
|
"time" <= $10
|
|
ELSE true
|
|
END
|
|
ORDER BY
|
|
"time" DESC
|
|
LIMIT
|
|
$1
|
|
OFFSET
|
|
$2
|
|
`
|
|
|
|
type GetAuditLogsOffsetParams struct {
|
|
Limit int32 `db:"limit" json:"limit"`
|
|
Offset int32 `db:"offset" json:"offset"`
|
|
ResourceType string `db:"resource_type" json:"resource_type"`
|
|
ResourceID uuid.UUID `db:"resource_id" json:"resource_id"`
|
|
ResourceTarget string `db:"resource_target" json:"resource_target"`
|
|
Action string `db:"action" json:"action"`
|
|
Username string `db:"username" json:"username"`
|
|
Email string `db:"email" json:"email"`
|
|
DateFrom time.Time `db:"date_from" json:"date_from"`
|
|
DateTo time.Time `db:"date_to" json:"date_to"`
|
|
}
|
|
|
|
type GetAuditLogsOffsetRow struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Time time.Time `db:"time" json:"time"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
Ip pqtype.Inet `db:"ip" json:"ip"`
|
|
UserAgent string `db:"user_agent" json:"user_agent"`
|
|
ResourceType ResourceType `db:"resource_type" json:"resource_type"`
|
|
ResourceID uuid.UUID `db:"resource_id" json:"resource_id"`
|
|
ResourceTarget string `db:"resource_target" json:"resource_target"`
|
|
Action AuditAction `db:"action" json:"action"`
|
|
Diff json.RawMessage `db:"diff" json:"diff"`
|
|
StatusCode int32 `db:"status_code" json:"status_code"`
|
|
AdditionalFields json.RawMessage `db:"additional_fields" json:"additional_fields"`
|
|
RequestID uuid.UUID `db:"request_id" json:"request_id"`
|
|
ResourceIcon string `db:"resource_icon" json:"resource_icon"`
|
|
UserUsername sql.NullString `db:"user_username" json:"user_username"`
|
|
UserEmail sql.NullString `db:"user_email" json:"user_email"`
|
|
UserCreatedAt sql.NullTime `db:"user_created_at" json:"user_created_at"`
|
|
UserStatus UserStatus `db:"user_status" json:"user_status"`
|
|
UserRoles []string `db:"user_roles" json:"user_roles"`
|
|
UserAvatarUrl sql.NullString `db:"user_avatar_url" json:"user_avatar_url"`
|
|
}
|
|
|
|
// GetAuditLogsBefore retrieves `row_limit` number of audit logs before the provided
|
|
// ID.
|
|
func (q *sqlQuerier) GetAuditLogsOffset(ctx context.Context, arg GetAuditLogsOffsetParams) ([]GetAuditLogsOffsetRow, error) {
|
|
rows, err := q.db.QueryContext(ctx, getAuditLogsOffset,
|
|
arg.Limit,
|
|
arg.Offset,
|
|
arg.ResourceType,
|
|
arg.ResourceID,
|
|
arg.ResourceTarget,
|
|
arg.Action,
|
|
arg.Username,
|
|
arg.Email,
|
|
arg.DateFrom,
|
|
arg.DateTo,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetAuditLogsOffsetRow
|
|
for rows.Next() {
|
|
var i GetAuditLogsOffsetRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Time,
|
|
&i.UserID,
|
|
&i.OrganizationID,
|
|
&i.Ip,
|
|
&i.UserAgent,
|
|
&i.ResourceType,
|
|
&i.ResourceID,
|
|
&i.ResourceTarget,
|
|
&i.Action,
|
|
&i.Diff,
|
|
&i.StatusCode,
|
|
&i.AdditionalFields,
|
|
&i.RequestID,
|
|
&i.ResourceIcon,
|
|
&i.UserUsername,
|
|
&i.UserEmail,
|
|
&i.UserCreatedAt,
|
|
&i.UserStatus,
|
|
pq.Array(&i.UserRoles),
|
|
&i.UserAvatarUrl,
|
|
); 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 insertAuditLog = `-- name: InsertAuditLog :one
|
|
INSERT INTO
|
|
audit_logs (
|
|
id,
|
|
"time",
|
|
user_id,
|
|
organization_id,
|
|
ip,
|
|
user_agent,
|
|
resource_type,
|
|
resource_id,
|
|
resource_target,
|
|
action,
|
|
diff,
|
|
status_code,
|
|
additional_fields,
|
|
request_id,
|
|
resource_icon
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING id, time, user_id, organization_id, ip, user_agent, resource_type, resource_id, resource_target, action, diff, status_code, additional_fields, request_id, resource_icon
|
|
`
|
|
|
|
type InsertAuditLogParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Time time.Time `db:"time" json:"time"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
Ip pqtype.Inet `db:"ip" json:"ip"`
|
|
UserAgent string `db:"user_agent" json:"user_agent"`
|
|
ResourceType ResourceType `db:"resource_type" json:"resource_type"`
|
|
ResourceID uuid.UUID `db:"resource_id" json:"resource_id"`
|
|
ResourceTarget string `db:"resource_target" json:"resource_target"`
|
|
Action AuditAction `db:"action" json:"action"`
|
|
Diff json.RawMessage `db:"diff" json:"diff"`
|
|
StatusCode int32 `db:"status_code" json:"status_code"`
|
|
AdditionalFields json.RawMessage `db:"additional_fields" json:"additional_fields"`
|
|
RequestID uuid.UUID `db:"request_id" json:"request_id"`
|
|
ResourceIcon string `db:"resource_icon" json:"resource_icon"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertAuditLog(ctx context.Context, arg InsertAuditLogParams) (AuditLog, error) {
|
|
row := q.db.QueryRowContext(ctx, insertAuditLog,
|
|
arg.ID,
|
|
arg.Time,
|
|
arg.UserID,
|
|
arg.OrganizationID,
|
|
arg.Ip,
|
|
arg.UserAgent,
|
|
arg.ResourceType,
|
|
arg.ResourceID,
|
|
arg.ResourceTarget,
|
|
arg.Action,
|
|
arg.Diff,
|
|
arg.StatusCode,
|
|
arg.AdditionalFields,
|
|
arg.RequestID,
|
|
arg.ResourceIcon,
|
|
)
|
|
var i AuditLog
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Time,
|
|
&i.UserID,
|
|
&i.OrganizationID,
|
|
&i.Ip,
|
|
&i.UserAgent,
|
|
&i.ResourceType,
|
|
&i.ResourceID,
|
|
&i.ResourceTarget,
|
|
&i.Action,
|
|
&i.Diff,
|
|
&i.StatusCode,
|
|
&i.AdditionalFields,
|
|
&i.RequestID,
|
|
&i.ResourceIcon,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getFileByHashAndCreator = `-- name: GetFileByHashAndCreator :one
|
|
SELECT
|
|
hash, created_at, created_by, mimetype, data, id
|
|
FROM
|
|
files
|
|
WHERE
|
|
hash = $1
|
|
AND
|
|
created_by = $2
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
type GetFileByHashAndCreatorParams struct {
|
|
Hash string `db:"hash" json:"hash"`
|
|
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetFileByHashAndCreator(ctx context.Context, arg GetFileByHashAndCreatorParams) (File, error) {
|
|
row := q.db.QueryRowContext(ctx, getFileByHashAndCreator, arg.Hash, arg.CreatedBy)
|
|
var i File
|
|
err := row.Scan(
|
|
&i.Hash,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
&i.Mimetype,
|
|
&i.Data,
|
|
&i.ID,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getFileByID = `-- name: GetFileByID :one
|
|
SELECT
|
|
hash, created_at, created_by, mimetype, data, id
|
|
FROM
|
|
files
|
|
WHERE
|
|
id = $1
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetFileByID(ctx context.Context, id uuid.UUID) (File, error) {
|
|
row := q.db.QueryRowContext(ctx, getFileByID, id)
|
|
var i File
|
|
err := row.Scan(
|
|
&i.Hash,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
&i.Mimetype,
|
|
&i.Data,
|
|
&i.ID,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertFile = `-- name: InsertFile :one
|
|
INSERT INTO
|
|
files (id, hash, created_at, created_by, mimetype, "data")
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6) RETURNING hash, created_at, created_by, mimetype, data, id
|
|
`
|
|
|
|
type InsertFileParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Hash string `db:"hash" json:"hash"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
|
|
Mimetype string `db:"mimetype" json:"mimetype"`
|
|
Data []byte `db:"data" json:"data"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertFile(ctx context.Context, arg InsertFileParams) (File, error) {
|
|
row := q.db.QueryRowContext(ctx, insertFile,
|
|
arg.ID,
|
|
arg.Hash,
|
|
arg.CreatedAt,
|
|
arg.CreatedBy,
|
|
arg.Mimetype,
|
|
arg.Data,
|
|
)
|
|
var i File
|
|
err := row.Scan(
|
|
&i.Hash,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
&i.Mimetype,
|
|
&i.Data,
|
|
&i.ID,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getGitAuthLink = `-- name: GetGitAuthLink :one
|
|
SELECT provider_id, user_id, created_at, updated_at, oauth_access_token, oauth_refresh_token, oauth_expiry FROM git_auth_links WHERE provider_id = $1 AND user_id = $2
|
|
`
|
|
|
|
type GetGitAuthLinkParams struct {
|
|
ProviderID string `db:"provider_id" json:"provider_id"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetGitAuthLink(ctx context.Context, arg GetGitAuthLinkParams) (GitAuthLink, error) {
|
|
row := q.db.QueryRowContext(ctx, getGitAuthLink, arg.ProviderID, arg.UserID)
|
|
var i GitAuthLink
|
|
err := row.Scan(
|
|
&i.ProviderID,
|
|
&i.UserID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OAuthAccessToken,
|
|
&i.OAuthRefreshToken,
|
|
&i.OAuthExpiry,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertGitAuthLink = `-- name: InsertGitAuthLink :one
|
|
INSERT INTO git_auth_links (
|
|
provider_id,
|
|
user_id,
|
|
created_at,
|
|
updated_at,
|
|
oauth_access_token,
|
|
oauth_refresh_token,
|
|
oauth_expiry
|
|
) VALUES (
|
|
$1,
|
|
$2,
|
|
$3,
|
|
$4,
|
|
$5,
|
|
$6,
|
|
$7
|
|
) RETURNING provider_id, user_id, created_at, updated_at, oauth_access_token, oauth_refresh_token, oauth_expiry
|
|
`
|
|
|
|
type InsertGitAuthLinkParams struct {
|
|
ProviderID string `db:"provider_id" json:"provider_id"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
OAuthAccessToken string `db:"oauth_access_token" json:"oauth_access_token"`
|
|
OAuthRefreshToken string `db:"oauth_refresh_token" json:"oauth_refresh_token"`
|
|
OAuthExpiry time.Time `db:"oauth_expiry" json:"oauth_expiry"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertGitAuthLink(ctx context.Context, arg InsertGitAuthLinkParams) (GitAuthLink, error) {
|
|
row := q.db.QueryRowContext(ctx, insertGitAuthLink,
|
|
arg.ProviderID,
|
|
arg.UserID,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.OAuthAccessToken,
|
|
arg.OAuthRefreshToken,
|
|
arg.OAuthExpiry,
|
|
)
|
|
var i GitAuthLink
|
|
err := row.Scan(
|
|
&i.ProviderID,
|
|
&i.UserID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OAuthAccessToken,
|
|
&i.OAuthRefreshToken,
|
|
&i.OAuthExpiry,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateGitAuthLink = `-- name: UpdateGitAuthLink :exec
|
|
UPDATE git_auth_links SET
|
|
updated_at = $3,
|
|
oauth_access_token = $4,
|
|
oauth_refresh_token = $5,
|
|
oauth_expiry = $6
|
|
WHERE provider_id = $1 AND user_id = $2
|
|
`
|
|
|
|
type UpdateGitAuthLinkParams struct {
|
|
ProviderID string `db:"provider_id" json:"provider_id"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
OAuthAccessToken string `db:"oauth_access_token" json:"oauth_access_token"`
|
|
OAuthRefreshToken string `db:"oauth_refresh_token" json:"oauth_refresh_token"`
|
|
OAuthExpiry time.Time `db:"oauth_expiry" json:"oauth_expiry"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateGitAuthLink(ctx context.Context, arg UpdateGitAuthLinkParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateGitAuthLink,
|
|
arg.ProviderID,
|
|
arg.UserID,
|
|
arg.UpdatedAt,
|
|
arg.OAuthAccessToken,
|
|
arg.OAuthRefreshToken,
|
|
arg.OAuthExpiry,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const deleteGitSSHKey = `-- name: DeleteGitSSHKey :exec
|
|
DELETE FROM
|
|
gitsshkeys
|
|
WHERE
|
|
user_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) DeleteGitSSHKey(ctx context.Context, userID uuid.UUID) error {
|
|
_, err := q.db.ExecContext(ctx, deleteGitSSHKey, userID)
|
|
return err
|
|
}
|
|
|
|
const getGitSSHKey = `-- name: GetGitSSHKey :one
|
|
SELECT
|
|
user_id, created_at, updated_at, private_key, public_key
|
|
FROM
|
|
gitsshkeys
|
|
WHERE
|
|
user_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetGitSSHKey(ctx context.Context, userID uuid.UUID) (GitSSHKey, error) {
|
|
row := q.db.QueryRowContext(ctx, getGitSSHKey, userID)
|
|
var i GitSSHKey
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.PrivateKey,
|
|
&i.PublicKey,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertGitSSHKey = `-- name: InsertGitSSHKey :one
|
|
INSERT INTO
|
|
gitsshkeys (
|
|
user_id,
|
|
created_at,
|
|
updated_at,
|
|
private_key,
|
|
public_key
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5) RETURNING user_id, created_at, updated_at, private_key, public_key
|
|
`
|
|
|
|
type InsertGitSSHKeyParams struct {
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
PrivateKey string `db:"private_key" json:"private_key"`
|
|
PublicKey string `db:"public_key" json:"public_key"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertGitSSHKey(ctx context.Context, arg InsertGitSSHKeyParams) (GitSSHKey, error) {
|
|
row := q.db.QueryRowContext(ctx, insertGitSSHKey,
|
|
arg.UserID,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.PrivateKey,
|
|
arg.PublicKey,
|
|
)
|
|
var i GitSSHKey
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.PrivateKey,
|
|
&i.PublicKey,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateGitSSHKey = `-- name: UpdateGitSSHKey :one
|
|
UPDATE
|
|
gitsshkeys
|
|
SET
|
|
updated_at = $2,
|
|
private_key = $3,
|
|
public_key = $4
|
|
WHERE
|
|
user_id = $1
|
|
RETURNING
|
|
user_id, created_at, updated_at, private_key, public_key
|
|
`
|
|
|
|
type UpdateGitSSHKeyParams struct {
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
PrivateKey string `db:"private_key" json:"private_key"`
|
|
PublicKey string `db:"public_key" json:"public_key"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateGitSSHKey(ctx context.Context, arg UpdateGitSSHKeyParams) (GitSSHKey, error) {
|
|
row := q.db.QueryRowContext(ctx, updateGitSSHKey,
|
|
arg.UserID,
|
|
arg.UpdatedAt,
|
|
arg.PrivateKey,
|
|
arg.PublicKey,
|
|
)
|
|
var i GitSSHKey
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.PrivateKey,
|
|
&i.PublicKey,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteGroupByID = `-- name: DeleteGroupByID :exec
|
|
DELETE FROM
|
|
groups
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) DeleteGroupByID(ctx context.Context, id uuid.UUID) error {
|
|
_, err := q.db.ExecContext(ctx, deleteGroupByID, id)
|
|
return err
|
|
}
|
|
|
|
const deleteGroupMember = `-- name: DeleteGroupMember :exec
|
|
DELETE FROM
|
|
group_members
|
|
WHERE
|
|
user_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) DeleteGroupMember(ctx context.Context, userID uuid.UUID) error {
|
|
_, err := q.db.ExecContext(ctx, deleteGroupMember, userID)
|
|
return err
|
|
}
|
|
|
|
const getAllOrganizationMembers = `-- name: GetAllOrganizationMembers :many
|
|
SELECT
|
|
users.id, users.email, users.username, users.hashed_password, users.created_at, users.updated_at, users.status, users.rbac_roles, users.login_type, users.avatar_url, users.deleted, users.last_seen_at
|
|
FROM
|
|
users
|
|
JOIN
|
|
organization_members
|
|
ON
|
|
users.id = organization_members.user_id
|
|
WHERE
|
|
organization_members.organization_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetAllOrganizationMembers(ctx context.Context, organizationID uuid.UUID) ([]User, error) {
|
|
rows, err := q.db.QueryContext(ctx, getAllOrganizationMembers, organizationID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []User
|
|
for rows.Next() {
|
|
var i User
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
); 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 getGroupByID = `-- name: GetGroupByID :one
|
|
SELECT
|
|
id, name, organization_id, avatar_url
|
|
FROM
|
|
groups
|
|
WHERE
|
|
id = $1
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetGroupByID(ctx context.Context, id uuid.UUID) (Group, error) {
|
|
row := q.db.QueryRowContext(ctx, getGroupByID, id)
|
|
var i Group
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.OrganizationID,
|
|
&i.AvatarURL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getGroupByOrgAndName = `-- name: GetGroupByOrgAndName :one
|
|
SELECT
|
|
id, name, organization_id, avatar_url
|
|
FROM
|
|
groups
|
|
WHERE
|
|
organization_id = $1
|
|
AND
|
|
name = $2
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
type GetGroupByOrgAndNameParams struct {
|
|
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
Name string `db:"name" json:"name"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetGroupByOrgAndName(ctx context.Context, arg GetGroupByOrgAndNameParams) (Group, error) {
|
|
row := q.db.QueryRowContext(ctx, getGroupByOrgAndName, arg.OrganizationID, arg.Name)
|
|
var i Group
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.OrganizationID,
|
|
&i.AvatarURL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getGroupMembers = `-- name: GetGroupMembers :many
|
|
SELECT
|
|
users.id, users.email, users.username, users.hashed_password, users.created_at, users.updated_at, users.status, users.rbac_roles, users.login_type, users.avatar_url, users.deleted, users.last_seen_at
|
|
FROM
|
|
users
|
|
JOIN
|
|
group_members
|
|
ON
|
|
users.id = group_members.user_id
|
|
WHERE
|
|
group_members.group_id = $1
|
|
AND
|
|
users.status = 'active'
|
|
AND
|
|
users.deleted = 'false'
|
|
`
|
|
|
|
func (q *sqlQuerier) GetGroupMembers(ctx context.Context, groupID uuid.UUID) ([]User, error) {
|
|
rows, err := q.db.QueryContext(ctx, getGroupMembers, groupID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []User
|
|
for rows.Next() {
|
|
var i User
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
); 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 getGroupsByOrganizationID = `-- name: GetGroupsByOrganizationID :many
|
|
SELECT
|
|
id, name, organization_id, avatar_url
|
|
FROM
|
|
groups
|
|
WHERE
|
|
organization_id = $1
|
|
AND
|
|
id != $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetGroupsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]Group, error) {
|
|
rows, err := q.db.QueryContext(ctx, getGroupsByOrganizationID, organizationID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []Group
|
|
for rows.Next() {
|
|
var i Group
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.OrganizationID,
|
|
&i.AvatarURL,
|
|
); 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 getUserGroups = `-- name: GetUserGroups :many
|
|
SELECT
|
|
groups.id, groups.name, groups.organization_id, groups.avatar_url
|
|
FROM
|
|
groups
|
|
JOIN
|
|
group_members
|
|
ON
|
|
groups.id = group_members.group_id
|
|
WHERE
|
|
group_members.user_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetUserGroups(ctx context.Context, userID uuid.UUID) ([]Group, error) {
|
|
rows, err := q.db.QueryContext(ctx, getUserGroups, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []Group
|
|
for rows.Next() {
|
|
var i Group
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.OrganizationID,
|
|
&i.AvatarURL,
|
|
); 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 insertAllUsersGroup = `-- name: InsertAllUsersGroup :one
|
|
INSERT INTO groups (
|
|
id,
|
|
name,
|
|
organization_id
|
|
)
|
|
VALUES
|
|
( $1, 'Everyone', $1) RETURNING id, name, organization_id, avatar_url
|
|
`
|
|
|
|
// We use the organization_id as the id
|
|
// for simplicity since all users is
|
|
// every member of the org.
|
|
func (q *sqlQuerier) InsertAllUsersGroup(ctx context.Context, organizationID uuid.UUID) (Group, error) {
|
|
row := q.db.QueryRowContext(ctx, insertAllUsersGroup, organizationID)
|
|
var i Group
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.OrganizationID,
|
|
&i.AvatarURL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertGroup = `-- name: InsertGroup :one
|
|
INSERT INTO groups (
|
|
id,
|
|
name,
|
|
organization_id,
|
|
avatar_url
|
|
)
|
|
VALUES
|
|
( $1, $2, $3, $4) RETURNING id, name, organization_id, avatar_url
|
|
`
|
|
|
|
type InsertGroupParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Name string `db:"name" json:"name"`
|
|
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
AvatarURL string `db:"avatar_url" json:"avatar_url"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertGroup(ctx context.Context, arg InsertGroupParams) (Group, error) {
|
|
row := q.db.QueryRowContext(ctx, insertGroup,
|
|
arg.ID,
|
|
arg.Name,
|
|
arg.OrganizationID,
|
|
arg.AvatarURL,
|
|
)
|
|
var i Group
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.OrganizationID,
|
|
&i.AvatarURL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertGroupMember = `-- name: InsertGroupMember :exec
|
|
INSERT INTO group_members (
|
|
user_id,
|
|
group_id
|
|
)
|
|
VALUES ( $1, $2)
|
|
`
|
|
|
|
type InsertGroupMemberParams struct {
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
GroupID uuid.UUID `db:"group_id" json:"group_id"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertGroupMember(ctx context.Context, arg InsertGroupMemberParams) error {
|
|
_, err := q.db.ExecContext(ctx, insertGroupMember, arg.UserID, arg.GroupID)
|
|
return err
|
|
}
|
|
|
|
const updateGroupByID = `-- name: UpdateGroupByID :one
|
|
UPDATE
|
|
groups
|
|
SET
|
|
name = $1,
|
|
avatar_url = $2
|
|
WHERE
|
|
id = $3
|
|
RETURNING id, name, organization_id, avatar_url
|
|
`
|
|
|
|
type UpdateGroupByIDParams struct {
|
|
Name string `db:"name" json:"name"`
|
|
AvatarURL string `db:"avatar_url" json:"avatar_url"`
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateGroupByID(ctx context.Context, arg UpdateGroupByIDParams) (Group, error) {
|
|
row := q.db.QueryRowContext(ctx, updateGroupByID, arg.Name, arg.AvatarURL, arg.ID)
|
|
var i Group
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.OrganizationID,
|
|
&i.AvatarURL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteLicense = `-- name: DeleteLicense :one
|
|
DELETE
|
|
FROM licenses
|
|
WHERE id = $1
|
|
RETURNING id
|
|
`
|
|
|
|
func (q *sqlQuerier) DeleteLicense(ctx context.Context, id int32) (int32, error) {
|
|
row := q.db.QueryRowContext(ctx, deleteLicense, id)
|
|
err := row.Scan(&id)
|
|
return id, err
|
|
}
|
|
|
|
const getLicenses = `-- name: GetLicenses :many
|
|
SELECT id, uploaded_at, jwt, exp
|
|
FROM licenses
|
|
ORDER BY (id)
|
|
`
|
|
|
|
func (q *sqlQuerier) GetLicenses(ctx context.Context) ([]License, error) {
|
|
rows, err := q.db.QueryContext(ctx, getLicenses)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []License
|
|
for rows.Next() {
|
|
var i License
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.UploadedAt,
|
|
&i.JWT,
|
|
&i.Exp,
|
|
); 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 getUnexpiredLicenses = `-- name: GetUnexpiredLicenses :many
|
|
SELECT id, uploaded_at, jwt, exp
|
|
FROM licenses
|
|
WHERE exp > NOW()
|
|
ORDER BY (id)
|
|
`
|
|
|
|
func (q *sqlQuerier) GetUnexpiredLicenses(ctx context.Context) ([]License, error) {
|
|
rows, err := q.db.QueryContext(ctx, getUnexpiredLicenses)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []License
|
|
for rows.Next() {
|
|
var i License
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.UploadedAt,
|
|
&i.JWT,
|
|
&i.Exp,
|
|
); 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 insertLicense = `-- name: InsertLicense :one
|
|
INSERT INTO
|
|
licenses (
|
|
uploaded_at,
|
|
jwt,
|
|
exp
|
|
)
|
|
VALUES
|
|
($1, $2, $3) RETURNING id, uploaded_at, jwt, exp
|
|
`
|
|
|
|
type InsertLicenseParams struct {
|
|
UploadedAt time.Time `db:"uploaded_at" json:"uploaded_at"`
|
|
JWT string `db:"jwt" json:"jwt"`
|
|
Exp time.Time `db:"exp" json:"exp"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertLicense(ctx context.Context, arg InsertLicenseParams) (License, error) {
|
|
row := q.db.QueryRowContext(ctx, insertLicense, arg.UploadedAt, arg.JWT, arg.Exp)
|
|
var i License
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.UploadedAt,
|
|
&i.JWT,
|
|
&i.Exp,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getOrganizationIDsByMemberIDs = `-- name: GetOrganizationIDsByMemberIDs :many
|
|
SELECT
|
|
user_id, array_agg(organization_id) :: uuid [ ] AS "organization_IDs"
|
|
FROM
|
|
organization_members
|
|
WHERE
|
|
user_id = ANY($1 :: uuid [ ])
|
|
GROUP BY
|
|
user_id
|
|
`
|
|
|
|
type GetOrganizationIDsByMemberIDsRow struct {
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
OrganizationIDs []uuid.UUID `db:"organization_IDs" json:"organization_IDs"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetOrganizationIDsByMemberIDs(ctx context.Context, ids []uuid.UUID) ([]GetOrganizationIDsByMemberIDsRow, error) {
|
|
rows, err := q.db.QueryContext(ctx, getOrganizationIDsByMemberIDs, pq.Array(ids))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetOrganizationIDsByMemberIDsRow
|
|
for rows.Next() {
|
|
var i GetOrganizationIDsByMemberIDsRow
|
|
if err := rows.Scan(&i.UserID, pq.Array(&i.OrganizationIDs)); 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 getOrganizationMemberByUserID = `-- name: GetOrganizationMemberByUserID :one
|
|
SELECT
|
|
user_id, organization_id, created_at, updated_at, roles
|
|
FROM
|
|
organization_members
|
|
WHERE
|
|
organization_id = $1
|
|
AND user_id = $2
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
type GetOrganizationMemberByUserIDParams struct {
|
|
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
UserID uuid.UUID `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.UserID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
pq.Array(&i.Roles),
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getOrganizationMembershipsByUserID = `-- name: GetOrganizationMembershipsByUserID :many
|
|
SELECT
|
|
user_id, organization_id, created_at, updated_at, roles
|
|
FROM
|
|
organization_members
|
|
WHERE
|
|
user_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetOrganizationMembershipsByUserID(ctx context.Context, userID uuid.UUID) ([]OrganizationMember, error) {
|
|
rows, err := q.db.QueryContext(ctx, getOrganizationMembershipsByUserID, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []OrganizationMember
|
|
for rows.Next() {
|
|
var i OrganizationMember
|
|
if err := rows.Scan(
|
|
&i.UserID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
pq.Array(&i.Roles),
|
|
); 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 insertOrganizationMember = `-- name: InsertOrganizationMember :one
|
|
INSERT INTO
|
|
organization_members (
|
|
organization_id,
|
|
user_id,
|
|
created_at,
|
|
updated_at,
|
|
roles
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5) RETURNING user_id, organization_id, created_at, updated_at, roles
|
|
`
|
|
|
|
type InsertOrganizationMemberParams struct {
|
|
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
Roles []string `db:"roles" json:"roles"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error) {
|
|
row := q.db.QueryRowContext(ctx, insertOrganizationMember,
|
|
arg.OrganizationID,
|
|
arg.UserID,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
pq.Array(arg.Roles),
|
|
)
|
|
var i OrganizationMember
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
pq.Array(&i.Roles),
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateMemberRoles = `-- name: UpdateMemberRoles :one
|
|
UPDATE
|
|
organization_members
|
|
SET
|
|
-- Remove all duplicates from the roles.
|
|
roles = ARRAY(SELECT DISTINCT UNNEST($1 :: text[]))
|
|
WHERE
|
|
user_id = $2
|
|
AND organization_id = $3
|
|
RETURNING user_id, organization_id, created_at, updated_at, roles
|
|
`
|
|
|
|
type UpdateMemberRolesParams struct {
|
|
GrantedRoles []string `db:"granted_roles" json:"granted_roles"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
OrgID uuid.UUID `db:"org_id" json:"org_id"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateMemberRoles(ctx context.Context, arg UpdateMemberRolesParams) (OrganizationMember, error) {
|
|
row := q.db.QueryRowContext(ctx, updateMemberRoles, pq.Array(arg.GrantedRoles), arg.UserID, arg.OrgID)
|
|
var i OrganizationMember
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
pq.Array(&i.Roles),
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getOrganizationByID = `-- name: GetOrganizationByID :one
|
|
SELECT
|
|
id, name, description, created_at, updated_at
|
|
FROM
|
|
organizations
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetOrganizationByID(ctx context.Context, id uuid.UUID) (Organization, error) {
|
|
row := q.db.QueryRowContext(ctx, getOrganizationByID, id)
|
|
var i Organization
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getOrganizationByName = `-- name: GetOrganizationByName :one
|
|
SELECT
|
|
id, name, description, created_at, updated_at
|
|
FROM
|
|
organizations
|
|
WHERE
|
|
LOWER("name") = LOWER($1)
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetOrganizationByName(ctx context.Context, name string) (Organization, error) {
|
|
row := q.db.QueryRowContext(ctx, getOrganizationByName, name)
|
|
var i Organization
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getOrganizations = `-- name: GetOrganizations :many
|
|
SELECT
|
|
id, name, description, created_at, updated_at
|
|
FROM
|
|
organizations
|
|
`
|
|
|
|
func (q *sqlQuerier) GetOrganizations(ctx context.Context) ([]Organization, error) {
|
|
rows, err := q.db.QueryContext(ctx, getOrganizations)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []Organization
|
|
for rows.Next() {
|
|
var i Organization
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
); 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 getOrganizationsByUserID = `-- name: GetOrganizationsByUserID :many
|
|
SELECT
|
|
id, name, description, created_at, updated_at
|
|
FROM
|
|
organizations
|
|
WHERE
|
|
id = (
|
|
SELECT
|
|
organization_id
|
|
FROM
|
|
organization_members
|
|
WHERE
|
|
user_id = $1
|
|
)
|
|
`
|
|
|
|
func (q *sqlQuerier) GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]Organization, error) {
|
|
rows, err := q.db.QueryContext(ctx, getOrganizationsByUserID, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []Organization
|
|
for rows.Next() {
|
|
var i Organization
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
); 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 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
|
|
`
|
|
|
|
type InsertOrganizationParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Name string `db:"name" json:"name"`
|
|
Description string `db:"description" json:"description"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, error) {
|
|
row := q.db.QueryRowContext(ctx, insertOrganization,
|
|
arg.ID,
|
|
arg.Name,
|
|
arg.Description,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
)
|
|
var i Organization
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getParameterSchemasByJobID = `-- name: GetParameterSchemasByJobID :many
|
|
SELECT
|
|
id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index
|
|
FROM
|
|
parameter_schemas
|
|
WHERE
|
|
job_id = $1
|
|
ORDER BY
|
|
index
|
|
`
|
|
|
|
func (q *sqlQuerier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]ParameterSchema, error) {
|
|
rows, err := q.db.QueryContext(ctx, getParameterSchemasByJobID, jobID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ParameterSchema
|
|
for rows.Next() {
|
|
var i ParameterSchema
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.JobID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.DefaultSourceScheme,
|
|
&i.DefaultSourceValue,
|
|
&i.AllowOverrideSource,
|
|
&i.DefaultDestinationScheme,
|
|
&i.AllowOverrideDestination,
|
|
&i.DefaultRefresh,
|
|
&i.RedisplayValue,
|
|
&i.ValidationError,
|
|
&i.ValidationCondition,
|
|
&i.ValidationTypeSystem,
|
|
&i.ValidationValueType,
|
|
&i.Index,
|
|
); 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 getParameterSchemasCreatedAfter = `-- name: GetParameterSchemasCreatedAfter :many
|
|
SELECT id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index FROM parameter_schemas WHERE created_at > $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]ParameterSchema, error) {
|
|
rows, err := q.db.QueryContext(ctx, getParameterSchemasCreatedAfter, createdAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ParameterSchema
|
|
for rows.Next() {
|
|
var i ParameterSchema
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.JobID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.DefaultSourceScheme,
|
|
&i.DefaultSourceValue,
|
|
&i.AllowOverrideSource,
|
|
&i.DefaultDestinationScheme,
|
|
&i.AllowOverrideDestination,
|
|
&i.DefaultRefresh,
|
|
&i.RedisplayValue,
|
|
&i.ValidationError,
|
|
&i.ValidationCondition,
|
|
&i.ValidationTypeSystem,
|
|
&i.ValidationValueType,
|
|
&i.Index,
|
|
); 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 insertParameterSchema = `-- name: InsertParameterSchema :one
|
|
INSERT INTO
|
|
parameter_schemas (
|
|
id,
|
|
created_at,
|
|
job_id,
|
|
"name",
|
|
description,
|
|
default_source_scheme,
|
|
default_source_value,
|
|
allow_override_source,
|
|
default_destination_scheme,
|
|
allow_override_destination,
|
|
default_refresh,
|
|
redisplay_value,
|
|
validation_error,
|
|
validation_condition,
|
|
validation_type_system,
|
|
validation_value_type,
|
|
index
|
|
)
|
|
VALUES
|
|
(
|
|
$1,
|
|
$2,
|
|
$3,
|
|
$4,
|
|
$5,
|
|
$6,
|
|
$7,
|
|
$8,
|
|
$9,
|
|
$10,
|
|
$11,
|
|
$12,
|
|
$13,
|
|
$14,
|
|
$15,
|
|
$16,
|
|
$17
|
|
) RETURNING id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index
|
|
`
|
|
|
|
type InsertParameterSchemaParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
|
Name string `db:"name" json:"name"`
|
|
Description string `db:"description" json:"description"`
|
|
DefaultSourceScheme ParameterSourceScheme `db:"default_source_scheme" json:"default_source_scheme"`
|
|
DefaultSourceValue string `db:"default_source_value" json:"default_source_value"`
|
|
AllowOverrideSource bool `db:"allow_override_source" json:"allow_override_source"`
|
|
DefaultDestinationScheme ParameterDestinationScheme `db:"default_destination_scheme" json:"default_destination_scheme"`
|
|
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"`
|
|
Index int32 `db:"index" json:"index"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertParameterSchema(ctx context.Context, arg InsertParameterSchemaParams) (ParameterSchema, error) {
|
|
row := q.db.QueryRowContext(ctx, insertParameterSchema,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.JobID,
|
|
arg.Name,
|
|
arg.Description,
|
|
arg.DefaultSourceScheme,
|
|
arg.DefaultSourceValue,
|
|
arg.AllowOverrideSource,
|
|
arg.DefaultDestinationScheme,
|
|
arg.AllowOverrideDestination,
|
|
arg.DefaultRefresh,
|
|
arg.RedisplayValue,
|
|
arg.ValidationError,
|
|
arg.ValidationCondition,
|
|
arg.ValidationTypeSystem,
|
|
arg.ValidationValueType,
|
|
arg.Index,
|
|
)
|
|
var i ParameterSchema
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.JobID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.DefaultSourceScheme,
|
|
&i.DefaultSourceValue,
|
|
&i.AllowOverrideSource,
|
|
&i.DefaultDestinationScheme,
|
|
&i.AllowOverrideDestination,
|
|
&i.DefaultRefresh,
|
|
&i.RedisplayValue,
|
|
&i.ValidationError,
|
|
&i.ValidationCondition,
|
|
&i.ValidationTypeSystem,
|
|
&i.ValidationValueType,
|
|
&i.Index,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteParameterValueByID = `-- name: DeleteParameterValueByID :exec
|
|
DELETE FROM
|
|
parameter_values
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error {
|
|
_, err := q.db.ExecContext(ctx, deleteParameterValueByID, id)
|
|
return err
|
|
}
|
|
|
|
const getParameterValueByScopeAndName = `-- name: GetParameterValueByScopeAndName :one
|
|
SELECT
|
|
id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
|
|
FROM
|
|
parameter_values
|
|
WHERE
|
|
scope = $1
|
|
AND scope_id = $2
|
|
AND NAME = $3
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
type GetParameterValueByScopeAndNameParams struct {
|
|
Scope ParameterScope `db:"scope" json:"scope"`
|
|
ScopeID uuid.UUID `db:"scope_id" json:"scope_id"`
|
|
Name string `db:"name" json:"name"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetParameterValueByScopeAndName(ctx context.Context, arg GetParameterValueByScopeAndNameParams) (ParameterValue, error) {
|
|
row := q.db.QueryRowContext(ctx, getParameterValueByScopeAndName, arg.Scope, arg.ScopeID, arg.Name)
|
|
var i ParameterValue
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Scope,
|
|
&i.ScopeID,
|
|
&i.Name,
|
|
&i.SourceScheme,
|
|
&i.SourceValue,
|
|
&i.DestinationScheme,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertParameterValue = `-- name: InsertParameterValue :one
|
|
INSERT INTO
|
|
parameter_values (
|
|
id,
|
|
"name",
|
|
created_at,
|
|
updated_at,
|
|
scope,
|
|
scope_id,
|
|
source_scheme,
|
|
source_value,
|
|
destination_scheme
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
|
|
`
|
|
|
|
type InsertParameterValueParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Name string `db:"name" json:"name"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
Scope ParameterScope `db:"scope" json:"scope"`
|
|
ScopeID uuid.UUID `db:"scope_id" json:"scope_id"`
|
|
SourceScheme ParameterSourceScheme `db:"source_scheme" json:"source_scheme"`
|
|
SourceValue string `db:"source_value" json:"source_value"`
|
|
DestinationScheme ParameterDestinationScheme `db:"destination_scheme" json:"destination_scheme"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertParameterValue(ctx context.Context, arg InsertParameterValueParams) (ParameterValue, error) {
|
|
row := q.db.QueryRowContext(ctx, insertParameterValue,
|
|
arg.ID,
|
|
arg.Name,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.Scope,
|
|
arg.ScopeID,
|
|
arg.SourceScheme,
|
|
arg.SourceValue,
|
|
arg.DestinationScheme,
|
|
)
|
|
var i ParameterValue
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Scope,
|
|
&i.ScopeID,
|
|
&i.Name,
|
|
&i.SourceScheme,
|
|
&i.SourceValue,
|
|
&i.DestinationScheme,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const parameterValue = `-- name: ParameterValue :one
|
|
SELECT id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme FROM
|
|
parameter_values
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) ParameterValue(ctx context.Context, id uuid.UUID) (ParameterValue, error) {
|
|
row := q.db.QueryRowContext(ctx, parameterValue, id)
|
|
var i ParameterValue
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Scope,
|
|
&i.ScopeID,
|
|
&i.Name,
|
|
&i.SourceScheme,
|
|
&i.SourceValue,
|
|
&i.DestinationScheme,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const parameterValues = `-- name: ParameterValues :many
|
|
SELECT
|
|
id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
|
|
FROM
|
|
parameter_values
|
|
WHERE
|
|
CASE
|
|
WHEN cardinality($1 :: parameter_scope[]) > 0 THEN
|
|
scope = ANY($1 :: parameter_scope[])
|
|
ELSE true
|
|
END
|
|
AND CASE
|
|
WHEN cardinality($2 :: uuid[]) > 0 THEN
|
|
scope_id = ANY($2 :: uuid[])
|
|
ELSE true
|
|
END
|
|
AND CASE
|
|
WHEN cardinality($3 :: uuid[]) > 0 THEN
|
|
id = ANY($3 :: uuid[])
|
|
ELSE true
|
|
END
|
|
AND CASE
|
|
WHEN cardinality($4 :: text[]) > 0 THEN
|
|
"name" = ANY($4 :: text[])
|
|
ELSE true
|
|
END
|
|
`
|
|
|
|
type ParameterValuesParams struct {
|
|
Scopes []ParameterScope `db:"scopes" json:"scopes"`
|
|
ScopeIds []uuid.UUID `db:"scope_ids" json:"scope_ids"`
|
|
IDs []uuid.UUID `db:"ids" json:"ids"`
|
|
Names []string `db:"names" json:"names"`
|
|
}
|
|
|
|
func (q *sqlQuerier) ParameterValues(ctx context.Context, arg ParameterValuesParams) ([]ParameterValue, error) {
|
|
rows, err := q.db.QueryContext(ctx, parameterValues,
|
|
pq.Array(arg.Scopes),
|
|
pq.Array(arg.ScopeIds),
|
|
pq.Array(arg.IDs),
|
|
pq.Array(arg.Names),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ParameterValue
|
|
for rows.Next() {
|
|
var i ParameterValue
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Scope,
|
|
&i.ScopeID,
|
|
&i.Name,
|
|
&i.SourceScheme,
|
|
&i.SourceValue,
|
|
&i.DestinationScheme,
|
|
); 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 getProvisionerDaemonByID = `-- name: GetProvisionerDaemonByID :one
|
|
SELECT
|
|
id, created_at, updated_at, name, provisioners, replica_id
|
|
FROM
|
|
provisioner_daemons
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetProvisionerDaemonByID(ctx context.Context, id uuid.UUID) (ProvisionerDaemon, error) {
|
|
row := q.db.QueryRowContext(ctx, getProvisionerDaemonByID, id)
|
|
var i ProvisionerDaemon
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
pq.Array(&i.Provisioners),
|
|
&i.ReplicaID,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getProvisionerDaemons = `-- name: GetProvisionerDaemons :many
|
|
SELECT
|
|
id, created_at, updated_at, name, provisioners, replica_id
|
|
FROM
|
|
provisioner_daemons
|
|
`
|
|
|
|
func (q *sqlQuerier) GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDaemon, error) {
|
|
rows, err := q.db.QueryContext(ctx, getProvisionerDaemons)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ProvisionerDaemon
|
|
for rows.Next() {
|
|
var i ProvisionerDaemon
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
pq.Array(&i.Provisioners),
|
|
&i.ReplicaID,
|
|
); 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 insertProvisionerDaemon = `-- name: InsertProvisionerDaemon :one
|
|
INSERT INTO
|
|
provisioner_daemons (
|
|
id,
|
|
created_at,
|
|
"name",
|
|
provisioners
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4) RETURNING id, created_at, updated_at, name, provisioners, replica_id
|
|
`
|
|
|
|
type InsertProvisionerDaemonParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
Name string `db:"name" json:"name"`
|
|
Provisioners []ProvisionerType `db:"provisioners" json:"provisioners"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertProvisionerDaemon(ctx context.Context, arg InsertProvisionerDaemonParams) (ProvisionerDaemon, error) {
|
|
row := q.db.QueryRowContext(ctx, insertProvisionerDaemon,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.Name,
|
|
pq.Array(arg.Provisioners),
|
|
)
|
|
var i ProvisionerDaemon
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
pq.Array(&i.Provisioners),
|
|
&i.ReplicaID,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateProvisionerDaemonByID = `-- name: UpdateProvisionerDaemonByID :exec
|
|
UPDATE
|
|
provisioner_daemons
|
|
SET
|
|
updated_at = $2,
|
|
provisioners = $3
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateProvisionerDaemonByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"`
|
|
Provisioners []ProvisionerType `db:"provisioners" json:"provisioners"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateProvisionerDaemonByID(ctx context.Context, arg UpdateProvisionerDaemonByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateProvisionerDaemonByID, arg.ID, arg.UpdatedAt, pq.Array(arg.Provisioners))
|
|
return err
|
|
}
|
|
|
|
const getProvisionerLogsByIDBetween = `-- name: GetProvisionerLogsByIDBetween :many
|
|
SELECT
|
|
job_id, created_at, source, level, stage, output, id
|
|
FROM
|
|
provisioner_job_logs
|
|
WHERE
|
|
job_id = $1
|
|
AND (
|
|
id > $2
|
|
OR id < $3
|
|
) ORDER BY id
|
|
`
|
|
|
|
type GetProvisionerLogsByIDBetweenParams struct {
|
|
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
|
CreatedAfter int64 `db:"created_after" json:"created_after"`
|
|
CreatedBefore int64 `db:"created_before" json:"created_before"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetProvisionerLogsByIDBetween(ctx context.Context, arg GetProvisionerLogsByIDBetweenParams) ([]ProvisionerJobLog, error) {
|
|
rows, err := q.db.QueryContext(ctx, getProvisionerLogsByIDBetween, arg.JobID, arg.CreatedAfter, arg.CreatedBefore)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ProvisionerJobLog
|
|
for rows.Next() {
|
|
var i ProvisionerJobLog
|
|
if err := rows.Scan(
|
|
&i.JobID,
|
|
&i.CreatedAt,
|
|
&i.Source,
|
|
&i.Level,
|
|
&i.Stage,
|
|
&i.Output,
|
|
&i.ID,
|
|
); 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 insertProvisionerJobLogs = `-- name: InsertProvisionerJobLogs :many
|
|
INSERT INTO
|
|
provisioner_job_logs
|
|
SELECT
|
|
$1 :: uuid AS job_id,
|
|
unnest($2 :: timestamptz [ ]) AS created_at,
|
|
unnest($3 :: log_source [ ]) AS source,
|
|
unnest($4 :: log_level [ ]) AS LEVEL,
|
|
unnest($5 :: VARCHAR(128) [ ]) AS stage,
|
|
unnest($6 :: VARCHAR(1024) [ ]) AS output RETURNING job_id, created_at, source, level, stage, output, id
|
|
`
|
|
|
|
type InsertProvisionerJobLogsParams struct {
|
|
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
|
CreatedAt []time.Time `db:"created_at" json:"created_at"`
|
|
Source []LogSource `db:"source" json:"source"`
|
|
Level []LogLevel `db:"level" json:"level"`
|
|
Stage []string `db:"stage" json:"stage"`
|
|
Output []string `db:"output" json:"output"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertProvisionerJobLogs(ctx context.Context, arg InsertProvisionerJobLogsParams) ([]ProvisionerJobLog, error) {
|
|
rows, err := q.db.QueryContext(ctx, insertProvisionerJobLogs,
|
|
arg.JobID,
|
|
pq.Array(arg.CreatedAt),
|
|
pq.Array(arg.Source),
|
|
pq.Array(arg.Level),
|
|
pq.Array(arg.Stage),
|
|
pq.Array(arg.Output),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ProvisionerJobLog
|
|
for rows.Next() {
|
|
var i ProvisionerJobLog
|
|
if err := rows.Scan(
|
|
&i.JobID,
|
|
&i.CreatedAt,
|
|
&i.Source,
|
|
&i.Level,
|
|
&i.Stage,
|
|
&i.Output,
|
|
&i.ID,
|
|
); 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 acquireProvisionerJob = `-- name: AcquireProvisionerJob :one
|
|
UPDATE
|
|
provisioner_jobs
|
|
SET
|
|
started_at = $1,
|
|
updated_at = $1,
|
|
worker_id = $2
|
|
WHERE
|
|
id = (
|
|
SELECT
|
|
id
|
|
FROM
|
|
provisioner_jobs AS nested
|
|
WHERE
|
|
nested.started_at IS NULL
|
|
AND nested.canceled_at IS NULL
|
|
AND nested.completed_at IS NULL
|
|
AND nested.provisioner = ANY($3 :: provisioner_type [ ])
|
|
ORDER BY
|
|
nested.created_at FOR
|
|
UPDATE
|
|
SKIP LOCKED
|
|
LIMIT
|
|
1
|
|
) RETURNING id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, type, input, worker_id, file_id
|
|
`
|
|
|
|
type AcquireProvisionerJobParams struct {
|
|
StartedAt sql.NullTime `db:"started_at" json:"started_at"`
|
|
WorkerID uuid.NullUUID `db:"worker_id" json:"worker_id"`
|
|
Types []ProvisionerType `db:"types" json:"types"`
|
|
}
|
|
|
|
// Acquires the lock for a single job that isn't started, completed,
|
|
// canceled, and that matches an array of provisioner types.
|
|
//
|
|
// SKIP LOCKED is used to jump over locked rows. This prevents
|
|
// multiple provisioners from acquiring the same jobs. See:
|
|
// https://www.postgresql.org/docs/9.5/sql-select.html#SQL-FOR-UPDATE-SHARE
|
|
func (q *sqlQuerier) AcquireProvisionerJob(ctx context.Context, arg AcquireProvisionerJobParams) (ProvisionerJob, error) {
|
|
row := q.db.QueryRowContext(ctx, acquireProvisionerJob, arg.StartedAt, arg.WorkerID, pq.Array(arg.Types))
|
|
var i ProvisionerJob
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.StartedAt,
|
|
&i.CanceledAt,
|
|
&i.CompletedAt,
|
|
&i.Error,
|
|
&i.OrganizationID,
|
|
&i.InitiatorID,
|
|
&i.Provisioner,
|
|
&i.StorageMethod,
|
|
&i.Type,
|
|
&i.Input,
|
|
&i.WorkerID,
|
|
&i.FileID,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getProvisionerJobByID = `-- name: GetProvisionerJobByID :one
|
|
SELECT
|
|
id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, type, input, worker_id, file_id
|
|
FROM
|
|
provisioner_jobs
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (ProvisionerJob, error) {
|
|
row := q.db.QueryRowContext(ctx, getProvisionerJobByID, id)
|
|
var i ProvisionerJob
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.StartedAt,
|
|
&i.CanceledAt,
|
|
&i.CompletedAt,
|
|
&i.Error,
|
|
&i.OrganizationID,
|
|
&i.InitiatorID,
|
|
&i.Provisioner,
|
|
&i.StorageMethod,
|
|
&i.Type,
|
|
&i.Input,
|
|
&i.WorkerID,
|
|
&i.FileID,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getProvisionerJobsByIDs = `-- name: GetProvisionerJobsByIDs :many
|
|
SELECT
|
|
id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, type, input, worker_id, file_id
|
|
FROM
|
|
provisioner_jobs
|
|
WHERE
|
|
id = ANY($1 :: uuid [ ])
|
|
`
|
|
|
|
func (q *sqlQuerier) GetProvisionerJobsByIDs(ctx context.Context, ids []uuid.UUID) ([]ProvisionerJob, error) {
|
|
rows, err := q.db.QueryContext(ctx, getProvisionerJobsByIDs, pq.Array(ids))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ProvisionerJob
|
|
for rows.Next() {
|
|
var i ProvisionerJob
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.StartedAt,
|
|
&i.CanceledAt,
|
|
&i.CompletedAt,
|
|
&i.Error,
|
|
&i.OrganizationID,
|
|
&i.InitiatorID,
|
|
&i.Provisioner,
|
|
&i.StorageMethod,
|
|
&i.Type,
|
|
&i.Input,
|
|
&i.WorkerID,
|
|
&i.FileID,
|
|
); 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 getProvisionerJobsCreatedAfter = `-- name: GetProvisionerJobsCreatedAfter :many
|
|
SELECT id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, type, input, worker_id, file_id FROM provisioner_jobs WHERE created_at > $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt time.Time) ([]ProvisionerJob, error) {
|
|
rows, err := q.db.QueryContext(ctx, getProvisionerJobsCreatedAfter, createdAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ProvisionerJob
|
|
for rows.Next() {
|
|
var i ProvisionerJob
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.StartedAt,
|
|
&i.CanceledAt,
|
|
&i.CompletedAt,
|
|
&i.Error,
|
|
&i.OrganizationID,
|
|
&i.InitiatorID,
|
|
&i.Provisioner,
|
|
&i.StorageMethod,
|
|
&i.Type,
|
|
&i.Input,
|
|
&i.WorkerID,
|
|
&i.FileID,
|
|
); 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 insertProvisionerJob = `-- name: InsertProvisionerJob :one
|
|
INSERT INTO
|
|
provisioner_jobs (
|
|
id,
|
|
created_at,
|
|
updated_at,
|
|
organization_id,
|
|
initiator_id,
|
|
provisioner,
|
|
storage_method,
|
|
file_id,
|
|
"type",
|
|
"input"
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, type, input, worker_id, file_id
|
|
`
|
|
|
|
type InsertProvisionerJobParams 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 uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
|
|
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
|
|
StorageMethod ProvisionerStorageMethod `db:"storage_method" json:"storage_method"`
|
|
FileID uuid.UUID `db:"file_id" json:"file_id"`
|
|
Type ProvisionerJobType `db:"type" json:"type"`
|
|
Input json.RawMessage `db:"input" json:"input"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error) {
|
|
row := q.db.QueryRowContext(ctx, insertProvisionerJob,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.OrganizationID,
|
|
arg.InitiatorID,
|
|
arg.Provisioner,
|
|
arg.StorageMethod,
|
|
arg.FileID,
|
|
arg.Type,
|
|
arg.Input,
|
|
)
|
|
var i ProvisionerJob
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.StartedAt,
|
|
&i.CanceledAt,
|
|
&i.CompletedAt,
|
|
&i.Error,
|
|
&i.OrganizationID,
|
|
&i.InitiatorID,
|
|
&i.Provisioner,
|
|
&i.StorageMethod,
|
|
&i.Type,
|
|
&i.Input,
|
|
&i.WorkerID,
|
|
&i.FileID,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateProvisionerJobByID = `-- name: UpdateProvisionerJobByID :exec
|
|
UPDATE
|
|
provisioner_jobs
|
|
SET
|
|
updated_at = $2
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateProvisionerJobByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateProvisionerJobByID(ctx context.Context, arg UpdateProvisionerJobByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateProvisionerJobByID, arg.ID, arg.UpdatedAt)
|
|
return err
|
|
}
|
|
|
|
const updateProvisionerJobWithCancelByID = `-- name: UpdateProvisionerJobWithCancelByID :exec
|
|
UPDATE
|
|
provisioner_jobs
|
|
SET
|
|
canceled_at = $2,
|
|
completed_at = $3
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateProvisionerJobWithCancelByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
CanceledAt sql.NullTime `db:"canceled_at" json:"canceled_at"`
|
|
CompletedAt sql.NullTime `db:"completed_at" json:"completed_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateProvisionerJobWithCancelByID(ctx context.Context, arg UpdateProvisionerJobWithCancelByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateProvisionerJobWithCancelByID, arg.ID, arg.CanceledAt, arg.CompletedAt)
|
|
return err
|
|
}
|
|
|
|
const updateProvisionerJobWithCompleteByID = `-- name: UpdateProvisionerJobWithCompleteByID :exec
|
|
UPDATE
|
|
provisioner_jobs
|
|
SET
|
|
updated_at = $2,
|
|
completed_at = $3,
|
|
error = $4
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateProvisionerJobWithCompleteByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
CompletedAt sql.NullTime `db:"completed_at" json:"completed_at"`
|
|
Error sql.NullString `db:"error" json:"error"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateProvisionerJobWithCompleteByID(ctx context.Context, arg UpdateProvisionerJobWithCompleteByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateProvisionerJobWithCompleteByID,
|
|
arg.ID,
|
|
arg.UpdatedAt,
|
|
arg.CompletedAt,
|
|
arg.Error,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const deleteReplicasUpdatedBefore = `-- name: DeleteReplicasUpdatedBefore :exec
|
|
DELETE FROM replicas WHERE updated_at < $1
|
|
`
|
|
|
|
func (q *sqlQuerier) DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error {
|
|
_, err := q.db.ExecContext(ctx, deleteReplicasUpdatedBefore, updatedAt)
|
|
return err
|
|
}
|
|
|
|
const getReplicasUpdatedAfter = `-- name: GetReplicasUpdatedAfter :many
|
|
SELECT id, created_at, started_at, stopped_at, updated_at, hostname, region_id, relay_address, database_latency, version, error FROM replicas WHERE updated_at > $1 AND stopped_at IS NULL
|
|
`
|
|
|
|
func (q *sqlQuerier) GetReplicasUpdatedAfter(ctx context.Context, updatedAt time.Time) ([]Replica, error) {
|
|
rows, err := q.db.QueryContext(ctx, getReplicasUpdatedAfter, updatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []Replica
|
|
for rows.Next() {
|
|
var i Replica
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.StartedAt,
|
|
&i.StoppedAt,
|
|
&i.UpdatedAt,
|
|
&i.Hostname,
|
|
&i.RegionID,
|
|
&i.RelayAddress,
|
|
&i.DatabaseLatency,
|
|
&i.Version,
|
|
&i.Error,
|
|
); 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 insertReplica = `-- name: InsertReplica :one
|
|
INSERT INTO replicas (
|
|
id,
|
|
created_at,
|
|
started_at,
|
|
updated_at,
|
|
hostname,
|
|
region_id,
|
|
relay_address,
|
|
version,
|
|
database_latency
|
|
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, created_at, started_at, stopped_at, updated_at, hostname, region_id, relay_address, database_latency, version, error
|
|
`
|
|
|
|
type InsertReplicaParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
StartedAt time.Time `db:"started_at" json:"started_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
Hostname string `db:"hostname" json:"hostname"`
|
|
RegionID int32 `db:"region_id" json:"region_id"`
|
|
RelayAddress string `db:"relay_address" json:"relay_address"`
|
|
Version string `db:"version" json:"version"`
|
|
DatabaseLatency int32 `db:"database_latency" json:"database_latency"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertReplica(ctx context.Context, arg InsertReplicaParams) (Replica, error) {
|
|
row := q.db.QueryRowContext(ctx, insertReplica,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.StartedAt,
|
|
arg.UpdatedAt,
|
|
arg.Hostname,
|
|
arg.RegionID,
|
|
arg.RelayAddress,
|
|
arg.Version,
|
|
arg.DatabaseLatency,
|
|
)
|
|
var i Replica
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.StartedAt,
|
|
&i.StoppedAt,
|
|
&i.UpdatedAt,
|
|
&i.Hostname,
|
|
&i.RegionID,
|
|
&i.RelayAddress,
|
|
&i.DatabaseLatency,
|
|
&i.Version,
|
|
&i.Error,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateReplica = `-- name: UpdateReplica :one
|
|
UPDATE replicas SET
|
|
updated_at = $2,
|
|
started_at = $3,
|
|
stopped_at = $4,
|
|
relay_address = $5,
|
|
region_id = $6,
|
|
hostname = $7,
|
|
version = $8,
|
|
error = $9,
|
|
database_latency = $10
|
|
WHERE id = $1 RETURNING id, created_at, started_at, stopped_at, updated_at, hostname, region_id, relay_address, database_latency, version, error
|
|
`
|
|
|
|
type UpdateReplicaParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
StartedAt time.Time `db:"started_at" json:"started_at"`
|
|
StoppedAt sql.NullTime `db:"stopped_at" json:"stopped_at"`
|
|
RelayAddress string `db:"relay_address" json:"relay_address"`
|
|
RegionID int32 `db:"region_id" json:"region_id"`
|
|
Hostname string `db:"hostname" json:"hostname"`
|
|
Version string `db:"version" json:"version"`
|
|
Error string `db:"error" json:"error"`
|
|
DatabaseLatency int32 `db:"database_latency" json:"database_latency"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateReplica(ctx context.Context, arg UpdateReplicaParams) (Replica, error) {
|
|
row := q.db.QueryRowContext(ctx, updateReplica,
|
|
arg.ID,
|
|
arg.UpdatedAt,
|
|
arg.StartedAt,
|
|
arg.StoppedAt,
|
|
arg.RelayAddress,
|
|
arg.RegionID,
|
|
arg.Hostname,
|
|
arg.Version,
|
|
arg.Error,
|
|
arg.DatabaseLatency,
|
|
)
|
|
var i Replica
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.StartedAt,
|
|
&i.StoppedAt,
|
|
&i.UpdatedAt,
|
|
&i.Hostname,
|
|
&i.RegionID,
|
|
&i.RelayAddress,
|
|
&i.DatabaseLatency,
|
|
&i.Version,
|
|
&i.Error,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getDERPMeshKey = `-- name: GetDERPMeshKey :one
|
|
SELECT value FROM site_configs WHERE key = 'derp_mesh_key'
|
|
`
|
|
|
|
func (q *sqlQuerier) GetDERPMeshKey(ctx context.Context) (string, error) {
|
|
row := q.db.QueryRowContext(ctx, getDERPMeshKey)
|
|
var value string
|
|
err := row.Scan(&value)
|
|
return value, err
|
|
}
|
|
|
|
const getDeploymentID = `-- name: GetDeploymentID :one
|
|
SELECT value FROM site_configs WHERE key = 'deployment_id'
|
|
`
|
|
|
|
func (q *sqlQuerier) GetDeploymentID(ctx context.Context) (string, error) {
|
|
row := q.db.QueryRowContext(ctx, getDeploymentID)
|
|
var value string
|
|
err := row.Scan(&value)
|
|
return value, err
|
|
}
|
|
|
|
const insertDERPMeshKey = `-- name: InsertDERPMeshKey :exec
|
|
INSERT INTO site_configs (key, value) VALUES ('derp_mesh_key', $1)
|
|
`
|
|
|
|
func (q *sqlQuerier) InsertDERPMeshKey(ctx context.Context, value string) error {
|
|
_, err := q.db.ExecContext(ctx, insertDERPMeshKey, value)
|
|
return err
|
|
}
|
|
|
|
const insertDeploymentID = `-- name: InsertDeploymentID :exec
|
|
INSERT INTO site_configs (key, value) VALUES ('deployment_id', $1)
|
|
`
|
|
|
|
func (q *sqlQuerier) InsertDeploymentID(ctx context.Context, value string) error {
|
|
_, err := q.db.ExecContext(ctx, insertDeploymentID, value)
|
|
return err
|
|
}
|
|
|
|
const getTemplateAverageBuildTime = `-- name: GetTemplateAverageBuildTime :one
|
|
WITH build_times AS (
|
|
SELECT
|
|
EXTRACT(EPOCH FROM (pj.completed_at - pj.started_at))::FLOAT AS exec_time_sec,
|
|
workspace_builds.transition
|
|
FROM
|
|
workspace_builds
|
|
JOIN template_versions ON
|
|
workspace_builds.template_version_id = template_versions.id
|
|
JOIN provisioner_jobs pj ON
|
|
workspace_builds.job_id = pj.id
|
|
WHERE
|
|
template_versions.template_id = $1 AND
|
|
(pj.completed_at IS NOT NULL) AND (pj.started_at IS NOT NULL) AND
|
|
(pj.started_at > $2) AND
|
|
(pj.canceled_at IS NULL) AND
|
|
((pj.error IS NULL) OR (pj.error = ''))
|
|
ORDER BY
|
|
workspace_builds.created_at DESC
|
|
)
|
|
SELECT
|
|
-- Postgres offers no clear way to DRY this short of a function or other
|
|
-- complexities.
|
|
coalesce((PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY exec_time_sec) FILTER (WHERE transition = 'start')), -1)::FLOAT AS start_median,
|
|
coalesce((PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY exec_time_sec) FILTER (WHERE transition = 'stop')), -1)::FLOAT AS stop_median,
|
|
coalesce((PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY exec_time_sec) FILTER (WHERE transition = 'delete')), -1)::FLOAT AS delete_median
|
|
FROM build_times
|
|
`
|
|
|
|
type GetTemplateAverageBuildTimeParams struct {
|
|
TemplateID uuid.NullUUID `db:"template_id" json:"template_id"`
|
|
StartTime sql.NullTime `db:"start_time" json:"start_time"`
|
|
}
|
|
|
|
type GetTemplateAverageBuildTimeRow struct {
|
|
StartMedian float64 `db:"start_median" json:"start_median"`
|
|
StopMedian float64 `db:"stop_median" json:"stop_median"`
|
|
DeleteMedian float64 `db:"delete_median" json:"delete_median"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetTemplateAverageBuildTime(ctx context.Context, arg GetTemplateAverageBuildTimeParams) (GetTemplateAverageBuildTimeRow, error) {
|
|
row := q.db.QueryRowContext(ctx, getTemplateAverageBuildTime, arg.TemplateID, arg.StartTime)
|
|
var i GetTemplateAverageBuildTimeRow
|
|
err := row.Scan(&i.StartMedian, &i.StopMedian, &i.DeleteMedian)
|
|
return i, err
|
|
}
|
|
|
|
const getTemplateByID = `-- name: GetTemplateByID :one
|
|
SELECT
|
|
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon, user_acl, group_acl
|
|
FROM
|
|
templates
|
|
WHERE
|
|
id = $1
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Template, error) {
|
|
row := q.db.QueryRowContext(ctx, getTemplateByID, id)
|
|
var i Template
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OrganizationID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.Provisioner,
|
|
&i.ActiveVersionID,
|
|
&i.Description,
|
|
&i.MaxTtl,
|
|
&i.MinAutostartInterval,
|
|
&i.CreatedBy,
|
|
&i.Icon,
|
|
&i.UserACL,
|
|
&i.GroupACL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getTemplateByOrganizationAndName = `-- name: GetTemplateByOrganizationAndName :one
|
|
SELECT
|
|
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon, user_acl, group_acl
|
|
FROM
|
|
templates
|
|
WHERE
|
|
organization_id = $1
|
|
AND deleted = $2
|
|
AND LOWER("name") = LOWER($3)
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
type GetTemplateByOrganizationAndNameParams struct {
|
|
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
Name string `db:"name" json:"name"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg GetTemplateByOrganizationAndNameParams) (Template, error) {
|
|
row := q.db.QueryRowContext(ctx, getTemplateByOrganizationAndName, arg.OrganizationID, arg.Deleted, arg.Name)
|
|
var i Template
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OrganizationID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.Provisioner,
|
|
&i.ActiveVersionID,
|
|
&i.Description,
|
|
&i.MaxTtl,
|
|
&i.MinAutostartInterval,
|
|
&i.CreatedBy,
|
|
&i.Icon,
|
|
&i.UserACL,
|
|
&i.GroupACL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getTemplates = `-- name: GetTemplates :many
|
|
SELECT id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon, user_acl, group_acl FROM templates
|
|
ORDER BY (name, id) ASC
|
|
`
|
|
|
|
func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
|
|
rows, err := q.db.QueryContext(ctx, getTemplates)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []Template
|
|
for rows.Next() {
|
|
var i Template
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OrganizationID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.Provisioner,
|
|
&i.ActiveVersionID,
|
|
&i.Description,
|
|
&i.MaxTtl,
|
|
&i.MinAutostartInterval,
|
|
&i.CreatedBy,
|
|
&i.Icon,
|
|
&i.UserACL,
|
|
&i.GroupACL,
|
|
); 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 getTemplatesWithFilter = `-- name: GetTemplatesWithFilter :many
|
|
SELECT
|
|
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon, user_acl, group_acl
|
|
FROM
|
|
templates
|
|
WHERE
|
|
-- Optionally include deleted templates
|
|
templates.deleted = $1
|
|
-- Filter by organization_id
|
|
AND CASE
|
|
WHEN $2 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
|
|
organization_id = $2
|
|
ELSE true
|
|
END
|
|
-- Filter by exact name
|
|
AND CASE
|
|
WHEN $3 :: text != '' THEN
|
|
LOWER("name") = LOWER($3)
|
|
ELSE true
|
|
END
|
|
-- Filter by ids
|
|
AND CASE
|
|
WHEN array_length($4 :: uuid[], 1) > 0 THEN
|
|
id = ANY($4)
|
|
ELSE true
|
|
END
|
|
ORDER BY (name, id) ASC
|
|
`
|
|
|
|
type GetTemplatesWithFilterParams struct {
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
ExactName string `db:"exact_name" json:"exact_name"`
|
|
IDs []uuid.UUID `db:"ids" json:"ids"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetTemplatesWithFilter(ctx context.Context, arg GetTemplatesWithFilterParams) ([]Template, error) {
|
|
rows, err := q.db.QueryContext(ctx, getTemplatesWithFilter,
|
|
arg.Deleted,
|
|
arg.OrganizationID,
|
|
arg.ExactName,
|
|
pq.Array(arg.IDs),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []Template
|
|
for rows.Next() {
|
|
var i Template
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OrganizationID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.Provisioner,
|
|
&i.ActiveVersionID,
|
|
&i.Description,
|
|
&i.MaxTtl,
|
|
&i.MinAutostartInterval,
|
|
&i.CreatedBy,
|
|
&i.Icon,
|
|
&i.UserACL,
|
|
&i.GroupACL,
|
|
); 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 insertTemplate = `-- name: InsertTemplate :one
|
|
INSERT INTO
|
|
templates (
|
|
id,
|
|
created_at,
|
|
updated_at,
|
|
organization_id,
|
|
"name",
|
|
provisioner,
|
|
active_version_id,
|
|
description,
|
|
max_ttl,
|
|
min_autostart_interval,
|
|
created_by,
|
|
icon,
|
|
user_acl,
|
|
group_acl
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) RETURNING id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon, user_acl, group_acl
|
|
`
|
|
|
|
type InsertTemplateParams 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 uuid.UUID `db:"organization_id" json:"organization_id"`
|
|
Name string `db:"name" json:"name"`
|
|
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
|
|
ActiveVersionID uuid.UUID `db:"active_version_id" json:"active_version_id"`
|
|
Description string `db:"description" json:"description"`
|
|
MaxTtl int64 `db:"max_ttl" json:"max_ttl"`
|
|
MinAutostartInterval int64 `db:"min_autostart_interval" json:"min_autostart_interval"`
|
|
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
|
|
Icon string `db:"icon" json:"icon"`
|
|
UserACL TemplateACL `db:"user_acl" json:"user_acl"`
|
|
GroupACL TemplateACL `db:"group_acl" json:"group_acl"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParams) (Template, error) {
|
|
row := q.db.QueryRowContext(ctx, insertTemplate,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.OrganizationID,
|
|
arg.Name,
|
|
arg.Provisioner,
|
|
arg.ActiveVersionID,
|
|
arg.Description,
|
|
arg.MaxTtl,
|
|
arg.MinAutostartInterval,
|
|
arg.CreatedBy,
|
|
arg.Icon,
|
|
arg.UserACL,
|
|
arg.GroupACL,
|
|
)
|
|
var i Template
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OrganizationID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.Provisioner,
|
|
&i.ActiveVersionID,
|
|
&i.Description,
|
|
&i.MaxTtl,
|
|
&i.MinAutostartInterval,
|
|
&i.CreatedBy,
|
|
&i.Icon,
|
|
&i.UserACL,
|
|
&i.GroupACL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateTemplateACLByID = `-- name: UpdateTemplateACLByID :one
|
|
UPDATE
|
|
templates
|
|
SET
|
|
group_acl = $1,
|
|
user_acl = $2
|
|
WHERE
|
|
id = $3
|
|
RETURNING
|
|
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon, user_acl, group_acl
|
|
`
|
|
|
|
type UpdateTemplateACLByIDParams struct {
|
|
GroupACL TemplateACL `db:"group_acl" json:"group_acl"`
|
|
UserACL TemplateACL `db:"user_acl" json:"user_acl"`
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateTemplateACLByID(ctx context.Context, arg UpdateTemplateACLByIDParams) (Template, error) {
|
|
row := q.db.QueryRowContext(ctx, updateTemplateACLByID, arg.GroupACL, arg.UserACL, arg.ID)
|
|
var i Template
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OrganizationID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.Provisioner,
|
|
&i.ActiveVersionID,
|
|
&i.Description,
|
|
&i.MaxTtl,
|
|
&i.MinAutostartInterval,
|
|
&i.CreatedBy,
|
|
&i.Icon,
|
|
&i.UserACL,
|
|
&i.GroupACL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateTemplateActiveVersionByID = `-- name: UpdateTemplateActiveVersionByID :exec
|
|
UPDATE
|
|
templates
|
|
SET
|
|
active_version_id = $2,
|
|
updated_at = $3
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateTemplateActiveVersionByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
ActiveVersionID uuid.UUID `db:"active_version_id" json:"active_version_id"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateTemplateActiveVersionByID(ctx context.Context, arg UpdateTemplateActiveVersionByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateTemplateActiveVersionByID, arg.ID, arg.ActiveVersionID, arg.UpdatedAt)
|
|
return err
|
|
}
|
|
|
|
const updateTemplateDeletedByID = `-- name: UpdateTemplateDeletedByID :exec
|
|
UPDATE
|
|
templates
|
|
SET
|
|
deleted = $2,
|
|
updated_at = $3
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateTemplateDeletedByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateTemplateDeletedByID(ctx context.Context, arg UpdateTemplateDeletedByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateTemplateDeletedByID, arg.ID, arg.Deleted, arg.UpdatedAt)
|
|
return err
|
|
}
|
|
|
|
const updateTemplateMetaByID = `-- name: UpdateTemplateMetaByID :one
|
|
UPDATE
|
|
templates
|
|
SET
|
|
updated_at = $2,
|
|
description = $3,
|
|
max_ttl = $4,
|
|
min_autostart_interval = $5,
|
|
name = $6,
|
|
icon = $7
|
|
WHERE
|
|
id = $1
|
|
RETURNING
|
|
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon, user_acl, group_acl
|
|
`
|
|
|
|
type UpdateTemplateMetaByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
Description string `db:"description" json:"description"`
|
|
MaxTtl int64 `db:"max_ttl" json:"max_ttl"`
|
|
MinAutostartInterval int64 `db:"min_autostart_interval" json:"min_autostart_interval"`
|
|
Name string `db:"name" json:"name"`
|
|
Icon string `db:"icon" json:"icon"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) (Template, error) {
|
|
row := q.db.QueryRowContext(ctx, updateTemplateMetaByID,
|
|
arg.ID,
|
|
arg.UpdatedAt,
|
|
arg.Description,
|
|
arg.MaxTtl,
|
|
arg.MinAutostartInterval,
|
|
arg.Name,
|
|
arg.Icon,
|
|
)
|
|
var i Template
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OrganizationID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.Provisioner,
|
|
&i.ActiveVersionID,
|
|
&i.Description,
|
|
&i.MaxTtl,
|
|
&i.MinAutostartInterval,
|
|
&i.CreatedBy,
|
|
&i.Icon,
|
|
&i.UserACL,
|
|
&i.GroupACL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getTemplateVersionByID = `-- name: GetTemplateVersionByID :one
|
|
SELECT
|
|
id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
|
|
FROM
|
|
template_versions
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (TemplateVersion, error) {
|
|
row := q.db.QueryRowContext(ctx, getTemplateVersionByID, id)
|
|
var i TemplateVersion
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.TemplateID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.Readme,
|
|
&i.JobID,
|
|
&i.CreatedBy,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getTemplateVersionByJobID = `-- name: GetTemplateVersionByJobID :one
|
|
SELECT
|
|
id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
|
|
FROM
|
|
template_versions
|
|
WHERE
|
|
job_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetTemplateVersionByJobID(ctx context.Context, jobID uuid.UUID) (TemplateVersion, error) {
|
|
row := q.db.QueryRowContext(ctx, getTemplateVersionByJobID, jobID)
|
|
var i TemplateVersion
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.TemplateID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.Readme,
|
|
&i.JobID,
|
|
&i.CreatedBy,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getTemplateVersionByTemplateIDAndName = `-- name: GetTemplateVersionByTemplateIDAndName :one
|
|
SELECT
|
|
id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
|
|
FROM
|
|
template_versions
|
|
WHERE
|
|
template_id = $1
|
|
AND "name" = $2
|
|
`
|
|
|
|
type GetTemplateVersionByTemplateIDAndNameParams struct {
|
|
TemplateID uuid.NullUUID `db:"template_id" json:"template_id"`
|
|
Name string `db:"name" json:"name"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetTemplateVersionByTemplateIDAndName(ctx context.Context, arg GetTemplateVersionByTemplateIDAndNameParams) (TemplateVersion, error) {
|
|
row := q.db.QueryRowContext(ctx, getTemplateVersionByTemplateIDAndName, arg.TemplateID, arg.Name)
|
|
var i TemplateVersion
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.TemplateID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.Readme,
|
|
&i.JobID,
|
|
&i.CreatedBy,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getTemplateVersionsByTemplateID = `-- name: GetTemplateVersionsByTemplateID :many
|
|
SELECT
|
|
id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
|
|
FROM
|
|
template_versions
|
|
WHERE
|
|
template_id = $1 :: uuid
|
|
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
|
|
-- duplicating or missing data.
|
|
WHEN $2 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN (
|
|
-- The pagination cursor is the last ID of the previous page.
|
|
-- The query is ordered by the created_at field, so select all
|
|
-- rows after the cursor.
|
|
(created_at, id) > (
|
|
SELECT
|
|
created_at, id
|
|
FROM
|
|
template_versions
|
|
WHERE
|
|
id = $2
|
|
)
|
|
)
|
|
ELSE true
|
|
END
|
|
ORDER BY
|
|
-- Deterministic and consistent ordering of all rows, even if they share
|
|
-- a timestamp. This is to ensure consistent pagination.
|
|
(created_at, id) ASC OFFSET $3
|
|
LIMIT
|
|
-- A null limit means "no limit", so 0 means return all
|
|
NULLIF($4 :: int, 0)
|
|
`
|
|
|
|
type GetTemplateVersionsByTemplateIDParams struct {
|
|
TemplateID uuid.UUID `db:"template_id" json:"template_id"`
|
|
AfterID uuid.UUID `db:"after_id" json:"after_id"`
|
|
OffsetOpt int32 `db:"offset_opt" json:"offset_opt"`
|
|
LimitOpt int32 `db:"limit_opt" json:"limit_opt"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetTemplateVersionsByTemplateID(ctx context.Context, arg GetTemplateVersionsByTemplateIDParams) ([]TemplateVersion, error) {
|
|
rows, err := q.db.QueryContext(ctx, getTemplateVersionsByTemplateID,
|
|
arg.TemplateID,
|
|
arg.AfterID,
|
|
arg.OffsetOpt,
|
|
arg.LimitOpt,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []TemplateVersion
|
|
for rows.Next() {
|
|
var i TemplateVersion
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TemplateID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.Readme,
|
|
&i.JobID,
|
|
&i.CreatedBy,
|
|
); 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 getTemplateVersionsCreatedAfter = `-- name: GetTemplateVersionsCreatedAfter :many
|
|
SELECT id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by FROM template_versions WHERE created_at > $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetTemplateVersionsCreatedAfter(ctx context.Context, createdAt time.Time) ([]TemplateVersion, error) {
|
|
rows, err := q.db.QueryContext(ctx, getTemplateVersionsCreatedAfter, createdAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []TemplateVersion
|
|
for rows.Next() {
|
|
var i TemplateVersion
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TemplateID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.Readme,
|
|
&i.JobID,
|
|
&i.CreatedBy,
|
|
); 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 insertTemplateVersion = `-- name: InsertTemplateVersion :one
|
|
INSERT INTO
|
|
template_versions (
|
|
id,
|
|
template_id,
|
|
organization_id,
|
|
created_at,
|
|
updated_at,
|
|
"name",
|
|
readme,
|
|
job_id,
|
|
created_by
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
|
|
`
|
|
|
|
type InsertTemplateVersionParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
TemplateID uuid.NullUUID `db:"template_id" json:"template_id"`
|
|
OrganizationID uuid.UUID `db:"organization_id" json:"organization_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"`
|
|
Readme string `db:"readme" json:"readme"`
|
|
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
|
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertTemplateVersion(ctx context.Context, arg InsertTemplateVersionParams) (TemplateVersion, error) {
|
|
row := q.db.QueryRowContext(ctx, insertTemplateVersion,
|
|
arg.ID,
|
|
arg.TemplateID,
|
|
arg.OrganizationID,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.Name,
|
|
arg.Readme,
|
|
arg.JobID,
|
|
arg.CreatedBy,
|
|
)
|
|
var i TemplateVersion
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.TemplateID,
|
|
&i.OrganizationID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.Readme,
|
|
&i.JobID,
|
|
&i.CreatedBy,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateTemplateVersionByID = `-- name: UpdateTemplateVersionByID :exec
|
|
UPDATE
|
|
template_versions
|
|
SET
|
|
template_id = $2,
|
|
updated_at = $3
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateTemplateVersionByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
TemplateID uuid.NullUUID `db:"template_id" json:"template_id"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateTemplateVersionByID(ctx context.Context, arg UpdateTemplateVersionByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateTemplateVersionByID, arg.ID, arg.TemplateID, arg.UpdatedAt)
|
|
return err
|
|
}
|
|
|
|
const updateTemplateVersionDescriptionByJobID = `-- name: UpdateTemplateVersionDescriptionByJobID :exec
|
|
UPDATE
|
|
template_versions
|
|
SET
|
|
readme = $2,
|
|
updated_at = $3
|
|
WHERE
|
|
job_id = $1
|
|
`
|
|
|
|
type UpdateTemplateVersionDescriptionByJobIDParams struct {
|
|
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
|
Readme string `db:"readme" json:"readme"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateTemplateVersionDescriptionByJobID(ctx context.Context, arg UpdateTemplateVersionDescriptionByJobIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateTemplateVersionDescriptionByJobID, arg.JobID, arg.Readme, arg.UpdatedAt)
|
|
return err
|
|
}
|
|
|
|
const getUserLinkByLinkedID = `-- name: GetUserLinkByLinkedID :one
|
|
SELECT
|
|
user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
|
|
FROM
|
|
user_links
|
|
WHERE
|
|
linked_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetUserLinkByLinkedID(ctx context.Context, linkedID string) (UserLink, error) {
|
|
row := q.db.QueryRowContext(ctx, getUserLinkByLinkedID, linkedID)
|
|
var i UserLink
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.LoginType,
|
|
&i.LinkedID,
|
|
&i.OAuthAccessToken,
|
|
&i.OAuthRefreshToken,
|
|
&i.OAuthExpiry,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getUserLinkByUserIDLoginType = `-- name: GetUserLinkByUserIDLoginType :one
|
|
SELECT
|
|
user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
|
|
FROM
|
|
user_links
|
|
WHERE
|
|
user_id = $1 AND login_type = $2
|
|
`
|
|
|
|
type GetUserLinkByUserIDLoginTypeParams struct {
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
LoginType LoginType `db:"login_type" json:"login_type"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetUserLinkByUserIDLoginType(ctx context.Context, arg GetUserLinkByUserIDLoginTypeParams) (UserLink, error) {
|
|
row := q.db.QueryRowContext(ctx, getUserLinkByUserIDLoginType, arg.UserID, arg.LoginType)
|
|
var i UserLink
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.LoginType,
|
|
&i.LinkedID,
|
|
&i.OAuthAccessToken,
|
|
&i.OAuthRefreshToken,
|
|
&i.OAuthExpiry,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertUserLink = `-- name: InsertUserLink :one
|
|
INSERT INTO
|
|
user_links (
|
|
user_id,
|
|
login_type,
|
|
linked_id,
|
|
oauth_access_token,
|
|
oauth_refresh_token,
|
|
oauth_expiry
|
|
)
|
|
VALUES
|
|
( $1, $2, $3, $4, $5, $6 ) RETURNING user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
|
|
`
|
|
|
|
type InsertUserLinkParams struct {
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
LoginType LoginType `db:"login_type" json:"login_type"`
|
|
LinkedID string `db:"linked_id" json:"linked_id"`
|
|
OAuthAccessToken string `db:"oauth_access_token" json:"oauth_access_token"`
|
|
OAuthRefreshToken string `db:"oauth_refresh_token" json:"oauth_refresh_token"`
|
|
OAuthExpiry time.Time `db:"oauth_expiry" json:"oauth_expiry"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertUserLink(ctx context.Context, arg InsertUserLinkParams) (UserLink, error) {
|
|
row := q.db.QueryRowContext(ctx, insertUserLink,
|
|
arg.UserID,
|
|
arg.LoginType,
|
|
arg.LinkedID,
|
|
arg.OAuthAccessToken,
|
|
arg.OAuthRefreshToken,
|
|
arg.OAuthExpiry,
|
|
)
|
|
var i UserLink
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.LoginType,
|
|
&i.LinkedID,
|
|
&i.OAuthAccessToken,
|
|
&i.OAuthRefreshToken,
|
|
&i.OAuthExpiry,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateUserLink = `-- name: UpdateUserLink :one
|
|
UPDATE
|
|
user_links
|
|
SET
|
|
oauth_access_token = $1,
|
|
oauth_refresh_token = $2,
|
|
oauth_expiry = $3
|
|
WHERE
|
|
user_id = $4 AND login_type = $5 RETURNING user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
|
|
`
|
|
|
|
type UpdateUserLinkParams struct {
|
|
OAuthAccessToken string `db:"oauth_access_token" json:"oauth_access_token"`
|
|
OAuthRefreshToken string `db:"oauth_refresh_token" json:"oauth_refresh_token"`
|
|
OAuthExpiry time.Time `db:"oauth_expiry" json:"oauth_expiry"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
LoginType LoginType `db:"login_type" json:"login_type"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateUserLink(ctx context.Context, arg UpdateUserLinkParams) (UserLink, error) {
|
|
row := q.db.QueryRowContext(ctx, updateUserLink,
|
|
arg.OAuthAccessToken,
|
|
arg.OAuthRefreshToken,
|
|
arg.OAuthExpiry,
|
|
arg.UserID,
|
|
arg.LoginType,
|
|
)
|
|
var i UserLink
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.LoginType,
|
|
&i.LinkedID,
|
|
&i.OAuthAccessToken,
|
|
&i.OAuthRefreshToken,
|
|
&i.OAuthExpiry,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateUserLinkedID = `-- name: UpdateUserLinkedID :one
|
|
UPDATE
|
|
user_links
|
|
SET
|
|
linked_id = $1
|
|
WHERE
|
|
user_id = $2 AND login_type = $3 RETURNING user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
|
|
`
|
|
|
|
type UpdateUserLinkedIDParams struct {
|
|
LinkedID string `db:"linked_id" json:"linked_id"`
|
|
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
|
LoginType LoginType `db:"login_type" json:"login_type"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateUserLinkedID(ctx context.Context, arg UpdateUserLinkedIDParams) (UserLink, error) {
|
|
row := q.db.QueryRowContext(ctx, updateUserLinkedID, arg.LinkedID, arg.UserID, arg.LoginType)
|
|
var i UserLink
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.LoginType,
|
|
&i.LinkedID,
|
|
&i.OAuthAccessToken,
|
|
&i.OAuthRefreshToken,
|
|
&i.OAuthExpiry,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getActiveUserCount = `-- name: GetActiveUserCount :one
|
|
SELECT
|
|
COUNT(*)
|
|
FROM
|
|
users
|
|
WHERE
|
|
status = 'active'::user_status AND deleted = false
|
|
`
|
|
|
|
func (q *sqlQuerier) GetActiveUserCount(ctx context.Context) (int64, error) {
|
|
row := q.db.QueryRowContext(ctx, getActiveUserCount)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const getAuthorizationUserRoles = `-- name: GetAuthorizationUserRoles :one
|
|
SELECT
|
|
-- username is returned just to help for logging purposes
|
|
-- status is used to enforce 'suspended' users, as all roles are ignored
|
|
-- when suspended.
|
|
id, username, status,
|
|
-- All user roles, including their org roles.
|
|
array_cat(
|
|
-- All users are members
|
|
array_append(users.rbac_roles, 'member'),
|
|
(
|
|
SELECT
|
|
array_agg(org_roles)
|
|
FROM
|
|
organization_members,
|
|
-- All org_members get the org-member role for their orgs
|
|
unnest(
|
|
array_append(roles, 'organization-member:' || organization_members.organization_id::text)
|
|
) AS org_roles
|
|
WHERE
|
|
user_id = users.id
|
|
)
|
|
) :: text[] AS roles,
|
|
-- All groups the user is in.
|
|
(
|
|
SELECT
|
|
array_agg(
|
|
group_members.group_id :: text
|
|
)
|
|
FROM
|
|
group_members
|
|
WHERE
|
|
user_id = users.id
|
|
) :: text[] AS groups
|
|
FROM
|
|
users
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type GetAuthorizationUserRolesRow struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Username string `db:"username" json:"username"`
|
|
Status UserStatus `db:"status" json:"status"`
|
|
Roles []string `db:"roles" json:"roles"`
|
|
Groups []string `db:"groups" json:"groups"`
|
|
}
|
|
|
|
// This function returns roles for authorization purposes. Implied member roles
|
|
// are included.
|
|
func (q *sqlQuerier) GetAuthorizationUserRoles(ctx context.Context, userID uuid.UUID) (GetAuthorizationUserRolesRow, error) {
|
|
row := q.db.QueryRowContext(ctx, getAuthorizationUserRoles, userID)
|
|
var i GetAuthorizationUserRolesRow
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Username,
|
|
&i.Status,
|
|
pq.Array(&i.Roles),
|
|
pq.Array(&i.Groups),
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getFilteredUserCount = `-- name: GetFilteredUserCount :one
|
|
SELECT
|
|
COUNT(*)
|
|
FROM
|
|
users
|
|
WHERE
|
|
users.deleted = $1
|
|
-- Start filters
|
|
-- Filter by name, email or username
|
|
AND CASE
|
|
WHEN $2 :: text != '' THEN (
|
|
email ILIKE concat('%', $2, '%')
|
|
OR username ILIKE concat('%', $2, '%')
|
|
)
|
|
ELSE true
|
|
END
|
|
-- Filter by status
|
|
AND CASE
|
|
-- @status needs to be a text because it can be empty, If it was
|
|
-- user_status enum, it would not.
|
|
WHEN cardinality($3 :: user_status[]) > 0 THEN
|
|
status = ANY($3 :: user_status[])
|
|
ELSE true
|
|
END
|
|
-- Filter by rbac_roles
|
|
AND CASE
|
|
-- @rbac_role allows filtering by rbac roles. If 'member' is included, show everyone, as everyone is a member.
|
|
WHEN cardinality($4 :: text[]) > 0 AND 'member' != ANY($4 :: text[])
|
|
THEN rbac_roles && $4 :: text[]
|
|
ELSE true
|
|
END
|
|
-- Authorize Filter clause will be injected below in GetAuthorizedUserCount
|
|
-- @authorize_filter
|
|
`
|
|
|
|
type GetFilteredUserCountParams struct {
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
Search string `db:"search" json:"search"`
|
|
Status []UserStatus `db:"status" json:"status"`
|
|
RbacRole []string `db:"rbac_role" json:"rbac_role"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetFilteredUserCount(ctx context.Context, arg GetFilteredUserCountParams) (int64, error) {
|
|
row := q.db.QueryRowContext(ctx, getFilteredUserCount,
|
|
arg.Deleted,
|
|
arg.Search,
|
|
pq.Array(arg.Status),
|
|
pq.Array(arg.RbacRole),
|
|
)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
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
|
|
FROM
|
|
users
|
|
WHERE
|
|
(LOWER(username) = LOWER($1) OR LOWER(email) = LOWER($2))
|
|
AND deleted = $3
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
type GetUserByEmailOrUsernameParams struct {
|
|
Username string `db:"username" json:"username"`
|
|
Email string `db:"email" json:"email"`
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetUserByEmailOrUsername(ctx context.Context, arg GetUserByEmailOrUsernameParams) (User, error) {
|
|
row := q.db.QueryRowContext(ctx, getUserByEmailOrUsername, arg.Username, arg.Email, arg.Deleted)
|
|
var i User
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
)
|
|
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
|
|
FROM
|
|
users
|
|
WHERE
|
|
id = $1
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetUserByID(ctx context.Context, id uuid.UUID) (User, error) {
|
|
row := q.db.QueryRowContext(ctx, getUserByID, id)
|
|
var i User
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getUserCount = `-- name: GetUserCount :one
|
|
SELECT
|
|
COUNT(*)
|
|
FROM
|
|
users WHERE deleted = false
|
|
`
|
|
|
|
func (q *sqlQuerier) GetUserCount(ctx context.Context) (int64, error) {
|
|
row := q.db.QueryRowContext(ctx, getUserCount)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
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
|
|
FROM
|
|
users
|
|
WHERE
|
|
users.deleted = $1
|
|
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
|
|
-- duplicating or missing data.
|
|
WHEN $2 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN (
|
|
-- The pagination cursor is the last ID of the previous page.
|
|
-- The query is ordered by the created_at field, so select all
|
|
-- rows after the cursor.
|
|
(created_at, id) > (
|
|
SELECT
|
|
created_at, id
|
|
FROM
|
|
users
|
|
WHERE
|
|
id = $2
|
|
)
|
|
)
|
|
ELSE true
|
|
END
|
|
-- Start filters
|
|
-- Filter by name, email or username
|
|
AND CASE
|
|
WHEN $3 :: text != '' THEN (
|
|
email ILIKE concat('%', $3, '%')
|
|
OR username ILIKE concat('%', $3, '%')
|
|
)
|
|
ELSE true
|
|
END
|
|
-- Filter by status
|
|
AND CASE
|
|
-- @status needs to be a text because it can be empty, If it was
|
|
-- user_status enum, it would not.
|
|
WHEN cardinality($4 :: user_status[]) > 0 THEN
|
|
status = ANY($4 :: user_status[])
|
|
ELSE true
|
|
END
|
|
-- Filter by rbac_roles
|
|
AND CASE
|
|
-- @rbac_role allows filtering by rbac roles. If 'member' is included, show everyone, as
|
|
-- everyone is a member.
|
|
WHEN cardinality($5 :: text[]) > 0 AND 'member' != ANY($5 :: text[]) THEN
|
|
rbac_roles && $5 :: text[]
|
|
ELSE true
|
|
END
|
|
-- End of filters
|
|
ORDER BY
|
|
-- Deterministic and consistent ordering of all users, even if they share
|
|
-- a timestamp. This is to ensure consistent pagination.
|
|
(created_at, id) ASC OFFSET $6
|
|
LIMIT
|
|
-- A null limit means "no limit", so 0 means return all
|
|
NULLIF($7 :: int, 0)
|
|
`
|
|
|
|
type GetUsersParams struct {
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
AfterID uuid.UUID `db:"after_id" json:"after_id"`
|
|
Search string `db:"search" json:"search"`
|
|
Status []UserStatus `db:"status" json:"status"`
|
|
RbacRole []string `db:"rbac_role" json:"rbac_role"`
|
|
OffsetOpt int32 `db:"offset_opt" json:"offset_opt"`
|
|
LimitOpt int32 `db:"limit_opt" json:"limit_opt"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetUsers(ctx context.Context, arg GetUsersParams) ([]User, error) {
|
|
rows, err := q.db.QueryContext(ctx, getUsers,
|
|
arg.Deleted,
|
|
arg.AfterID,
|
|
arg.Search,
|
|
pq.Array(arg.Status),
|
|
pq.Array(arg.RbacRole),
|
|
arg.OffsetOpt,
|
|
arg.LimitOpt,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []User
|
|
for rows.Next() {
|
|
var i User
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
); 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 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 FROM users WHERE id = ANY($1 :: uuid [ ])
|
|
`
|
|
|
|
// This shouldn't check for deleted, because it's frequently used
|
|
// to look up references to actions. eg. a user could build a workspace
|
|
// for another user, then be deleted... we still want them to appear!
|
|
func (q *sqlQuerier) GetUsersByIDs(ctx context.Context, ids []uuid.UUID) ([]User, error) {
|
|
rows, err := q.db.QueryContext(ctx, getUsersByIDs, pq.Array(ids))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []User
|
|
for rows.Next() {
|
|
var i User
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
); 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 insertUser = `-- name: InsertUser :one
|
|
INSERT INTO
|
|
users (
|
|
id,
|
|
email,
|
|
username,
|
|
hashed_password,
|
|
created_at,
|
|
updated_at,
|
|
rbac_roles,
|
|
login_type
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at
|
|
`
|
|
|
|
type InsertUserParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Email string `db:"email" json:"email"`
|
|
Username string `db:"username" json:"username"`
|
|
HashedPassword []byte `db:"hashed_password" json:"hashed_password"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
RBACRoles pq.StringArray `db:"rbac_roles" json:"rbac_roles"`
|
|
LoginType LoginType `db:"login_type" json:"login_type"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertUser(ctx context.Context, arg InsertUserParams) (User, error) {
|
|
row := q.db.QueryRowContext(ctx, insertUser,
|
|
arg.ID,
|
|
arg.Email,
|
|
arg.Username,
|
|
arg.HashedPassword,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.RBACRoles,
|
|
arg.LoginType,
|
|
)
|
|
var i User
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateUserDeletedByID = `-- name: UpdateUserDeletedByID :exec
|
|
UPDATE
|
|
users
|
|
SET
|
|
deleted = $2
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateUserDeletedByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateUserDeletedByID(ctx context.Context, arg UpdateUserDeletedByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateUserDeletedByID, arg.ID, arg.Deleted)
|
|
return err
|
|
}
|
|
|
|
const updateUserHashedPassword = `-- name: UpdateUserHashedPassword :exec
|
|
UPDATE
|
|
users
|
|
SET
|
|
hashed_password = $2
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateUserHashedPasswordParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
HashedPassword []byte `db:"hashed_password" json:"hashed_password"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateUserHashedPassword(ctx context.Context, arg UpdateUserHashedPasswordParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateUserHashedPassword, arg.ID, arg.HashedPassword)
|
|
return err
|
|
}
|
|
|
|
const updateUserLastSeenAt = `-- name: UpdateUserLastSeenAt :one
|
|
UPDATE
|
|
users
|
|
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
|
|
`
|
|
|
|
type UpdateUserLastSeenAtParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
LastSeenAt time.Time `db:"last_seen_at" json:"last_seen_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateUserLastSeenAt(ctx context.Context, arg UpdateUserLastSeenAtParams) (User, error) {
|
|
row := q.db.QueryRowContext(ctx, updateUserLastSeenAt, arg.ID, arg.LastSeenAt, arg.UpdatedAt)
|
|
var i User
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateUserProfile = `-- name: UpdateUserProfile :one
|
|
UPDATE
|
|
users
|
|
SET
|
|
email = $2,
|
|
username = $3,
|
|
avatar_url = $4,
|
|
updated_at = $5
|
|
WHERE
|
|
id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at
|
|
`
|
|
|
|
type UpdateUserProfileParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Email string `db:"email" json:"email"`
|
|
Username string `db:"username" json:"username"`
|
|
AvatarURL sql.NullString `db:"avatar_url" json:"avatar_url"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateUserProfile(ctx context.Context, arg UpdateUserProfileParams) (User, error) {
|
|
row := q.db.QueryRowContext(ctx, updateUserProfile,
|
|
arg.ID,
|
|
arg.Email,
|
|
arg.Username,
|
|
arg.AvatarURL,
|
|
arg.UpdatedAt,
|
|
)
|
|
var i User
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateUserRoles = `-- name: UpdateUserRoles :one
|
|
UPDATE
|
|
users
|
|
SET
|
|
-- Remove all duplicates from the roles.
|
|
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
|
|
`
|
|
|
|
type UpdateUserRolesParams struct {
|
|
GrantedRoles []string `db:"granted_roles" json:"granted_roles"`
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateUserRoles(ctx context.Context, arg UpdateUserRolesParams) (User, error) {
|
|
row := q.db.QueryRowContext(ctx, updateUserRoles, pq.Array(arg.GrantedRoles), arg.ID)
|
|
var i User
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateUserStatus = `-- name: UpdateUserStatus :one
|
|
UPDATE
|
|
users
|
|
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
|
|
`
|
|
|
|
type UpdateUserStatusParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Status UserStatus `db:"status" json:"status"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateUserStatus(ctx context.Context, arg UpdateUserStatusParams) (User, error) {
|
|
row := q.db.QueryRowContext(ctx, updateUserStatus, arg.ID, arg.Status, arg.UpdatedAt)
|
|
var i User
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Email,
|
|
&i.Username,
|
|
&i.HashedPassword,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Status,
|
|
&i.RBACRoles,
|
|
&i.LoginType,
|
|
&i.AvatarURL,
|
|
&i.Deleted,
|
|
&i.LastSeenAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceAgentByAuthToken = `-- name: GetWorkspaceAgentByAuthToken :one
|
|
SELECT
|
|
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url
|
|
FROM
|
|
workspace_agents
|
|
WHERE
|
|
auth_token = $1
|
|
ORDER BY
|
|
created_at DESC
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceAgentByAuthToken(ctx context.Context, authToken uuid.UUID) (WorkspaceAgent, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceAgentByAuthToken, authToken)
|
|
var i WorkspaceAgent
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.FirstConnectedAt,
|
|
&i.LastConnectedAt,
|
|
&i.DisconnectedAt,
|
|
&i.ResourceID,
|
|
&i.AuthToken,
|
|
&i.AuthInstanceID,
|
|
&i.Architecture,
|
|
&i.EnvironmentVariables,
|
|
&i.OperatingSystem,
|
|
&i.StartupScript,
|
|
&i.InstanceMetadata,
|
|
&i.ResourceMetadata,
|
|
&i.Directory,
|
|
&i.Version,
|
|
&i.LastConnectedReplicaID,
|
|
&i.ConnectionTimeoutSeconds,
|
|
&i.TroubleshootingURL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceAgentByID = `-- name: GetWorkspaceAgentByID :one
|
|
SELECT
|
|
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url
|
|
FROM
|
|
workspace_agents
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceAgentByID(ctx context.Context, id uuid.UUID) (WorkspaceAgent, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceAgentByID, id)
|
|
var i WorkspaceAgent
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.FirstConnectedAt,
|
|
&i.LastConnectedAt,
|
|
&i.DisconnectedAt,
|
|
&i.ResourceID,
|
|
&i.AuthToken,
|
|
&i.AuthInstanceID,
|
|
&i.Architecture,
|
|
&i.EnvironmentVariables,
|
|
&i.OperatingSystem,
|
|
&i.StartupScript,
|
|
&i.InstanceMetadata,
|
|
&i.ResourceMetadata,
|
|
&i.Directory,
|
|
&i.Version,
|
|
&i.LastConnectedReplicaID,
|
|
&i.ConnectionTimeoutSeconds,
|
|
&i.TroubleshootingURL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceAgentByInstanceID = `-- name: GetWorkspaceAgentByInstanceID :one
|
|
SELECT
|
|
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url
|
|
FROM
|
|
workspace_agents
|
|
WHERE
|
|
auth_instance_id = $1 :: TEXT
|
|
ORDER BY
|
|
created_at DESC
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceAgentByInstanceID(ctx context.Context, authInstanceID string) (WorkspaceAgent, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceAgentByInstanceID, authInstanceID)
|
|
var i WorkspaceAgent
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.FirstConnectedAt,
|
|
&i.LastConnectedAt,
|
|
&i.DisconnectedAt,
|
|
&i.ResourceID,
|
|
&i.AuthToken,
|
|
&i.AuthInstanceID,
|
|
&i.Architecture,
|
|
&i.EnvironmentVariables,
|
|
&i.OperatingSystem,
|
|
&i.StartupScript,
|
|
&i.InstanceMetadata,
|
|
&i.ResourceMetadata,
|
|
&i.Directory,
|
|
&i.Version,
|
|
&i.LastConnectedReplicaID,
|
|
&i.ConnectionTimeoutSeconds,
|
|
&i.TroubleshootingURL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceAgentsByResourceIDs = `-- name: GetWorkspaceAgentsByResourceIDs :many
|
|
SELECT
|
|
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url
|
|
FROM
|
|
workspace_agents
|
|
WHERE
|
|
resource_id = ANY($1 :: uuid [ ])
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgent, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceAgentsByResourceIDs, pq.Array(ids))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceAgent
|
|
for rows.Next() {
|
|
var i WorkspaceAgent
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.FirstConnectedAt,
|
|
&i.LastConnectedAt,
|
|
&i.DisconnectedAt,
|
|
&i.ResourceID,
|
|
&i.AuthToken,
|
|
&i.AuthInstanceID,
|
|
&i.Architecture,
|
|
&i.EnvironmentVariables,
|
|
&i.OperatingSystem,
|
|
&i.StartupScript,
|
|
&i.InstanceMetadata,
|
|
&i.ResourceMetadata,
|
|
&i.Directory,
|
|
&i.Version,
|
|
&i.LastConnectedReplicaID,
|
|
&i.ConnectionTimeoutSeconds,
|
|
&i.TroubleshootingURL,
|
|
); 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 getWorkspaceAgentsCreatedAfter = `-- name: GetWorkspaceAgentsCreatedAfter :many
|
|
SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url FROM workspace_agents WHERE created_at > $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceAgent, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceAgentsCreatedAfter, createdAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceAgent
|
|
for rows.Next() {
|
|
var i WorkspaceAgent
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.FirstConnectedAt,
|
|
&i.LastConnectedAt,
|
|
&i.DisconnectedAt,
|
|
&i.ResourceID,
|
|
&i.AuthToken,
|
|
&i.AuthInstanceID,
|
|
&i.Architecture,
|
|
&i.EnvironmentVariables,
|
|
&i.OperatingSystem,
|
|
&i.StartupScript,
|
|
&i.InstanceMetadata,
|
|
&i.ResourceMetadata,
|
|
&i.Directory,
|
|
&i.Version,
|
|
&i.LastConnectedReplicaID,
|
|
&i.ConnectionTimeoutSeconds,
|
|
&i.TroubleshootingURL,
|
|
); 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 insertWorkspaceAgent = `-- name: InsertWorkspaceAgent :one
|
|
INSERT INTO
|
|
workspace_agents (
|
|
id,
|
|
created_at,
|
|
updated_at,
|
|
name,
|
|
resource_id,
|
|
auth_token,
|
|
auth_instance_id,
|
|
architecture,
|
|
environment_variables,
|
|
operating_system,
|
|
startup_script,
|
|
directory,
|
|
instance_metadata,
|
|
resource_metadata,
|
|
connection_timeout_seconds,
|
|
troubleshooting_url
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url
|
|
`
|
|
|
|
type InsertWorkspaceAgentParams 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"`
|
|
Name string `db:"name" json:"name"`
|
|
ResourceID uuid.UUID `db:"resource_id" json:"resource_id"`
|
|
AuthToken uuid.UUID `db:"auth_token" json:"auth_token"`
|
|
AuthInstanceID sql.NullString `db:"auth_instance_id" json:"auth_instance_id"`
|
|
Architecture string `db:"architecture" json:"architecture"`
|
|
EnvironmentVariables pqtype.NullRawMessage `db:"environment_variables" json:"environment_variables"`
|
|
OperatingSystem string `db:"operating_system" json:"operating_system"`
|
|
StartupScript sql.NullString `db:"startup_script" json:"startup_script"`
|
|
Directory string `db:"directory" json:"directory"`
|
|
InstanceMetadata pqtype.NullRawMessage `db:"instance_metadata" json:"instance_metadata"`
|
|
ResourceMetadata pqtype.NullRawMessage `db:"resource_metadata" json:"resource_metadata"`
|
|
ConnectionTimeoutSeconds int32 `db:"connection_timeout_seconds" json:"connection_timeout_seconds"`
|
|
TroubleshootingURL string `db:"troubleshooting_url" json:"troubleshooting_url"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspaceAgentParams) (WorkspaceAgent, error) {
|
|
row := q.db.QueryRowContext(ctx, insertWorkspaceAgent,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.Name,
|
|
arg.ResourceID,
|
|
arg.AuthToken,
|
|
arg.AuthInstanceID,
|
|
arg.Architecture,
|
|
arg.EnvironmentVariables,
|
|
arg.OperatingSystem,
|
|
arg.StartupScript,
|
|
arg.Directory,
|
|
arg.InstanceMetadata,
|
|
arg.ResourceMetadata,
|
|
arg.ConnectionTimeoutSeconds,
|
|
arg.TroubleshootingURL,
|
|
)
|
|
var i WorkspaceAgent
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Name,
|
|
&i.FirstConnectedAt,
|
|
&i.LastConnectedAt,
|
|
&i.DisconnectedAt,
|
|
&i.ResourceID,
|
|
&i.AuthToken,
|
|
&i.AuthInstanceID,
|
|
&i.Architecture,
|
|
&i.EnvironmentVariables,
|
|
&i.OperatingSystem,
|
|
&i.StartupScript,
|
|
&i.InstanceMetadata,
|
|
&i.ResourceMetadata,
|
|
&i.Directory,
|
|
&i.Version,
|
|
&i.LastConnectedReplicaID,
|
|
&i.ConnectionTimeoutSeconds,
|
|
&i.TroubleshootingURL,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateWorkspaceAgentConnectionByID = `-- name: UpdateWorkspaceAgentConnectionByID :exec
|
|
UPDATE
|
|
workspace_agents
|
|
SET
|
|
first_connected_at = $2,
|
|
last_connected_at = $3,
|
|
last_connected_replica_id = $4,
|
|
disconnected_at = $5,
|
|
updated_at = $6
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateWorkspaceAgentConnectionByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
FirstConnectedAt sql.NullTime `db:"first_connected_at" json:"first_connected_at"`
|
|
LastConnectedAt sql.NullTime `db:"last_connected_at" json:"last_connected_at"`
|
|
LastConnectedReplicaID uuid.NullUUID `db:"last_connected_replica_id" json:"last_connected_replica_id"`
|
|
DisconnectedAt sql.NullTime `db:"disconnected_at" json:"disconnected_at"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateWorkspaceAgentConnectionByID(ctx context.Context, arg UpdateWorkspaceAgentConnectionByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateWorkspaceAgentConnectionByID,
|
|
arg.ID,
|
|
arg.FirstConnectedAt,
|
|
arg.LastConnectedAt,
|
|
arg.LastConnectedReplicaID,
|
|
arg.DisconnectedAt,
|
|
arg.UpdatedAt,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const updateWorkspaceAgentVersionByID = `-- name: UpdateWorkspaceAgentVersionByID :exec
|
|
UPDATE
|
|
workspace_agents
|
|
SET
|
|
version = $2
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateWorkspaceAgentVersionByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Version string `db:"version" json:"version"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateWorkspaceAgentVersionByID(ctx context.Context, arg UpdateWorkspaceAgentVersionByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateWorkspaceAgentVersionByID, arg.ID, arg.Version)
|
|
return err
|
|
}
|
|
|
|
const getWorkspaceAppByAgentIDAndSlug = `-- name: GetWorkspaceAppByAgentIDAndSlug :one
|
|
SELECT id, created_at, agent_id, display_name, icon, command, url, healthcheck_url, healthcheck_interval, healthcheck_threshold, health, subdomain, sharing_level, slug FROM workspace_apps WHERE agent_id = $1 AND slug = $2
|
|
`
|
|
|
|
type GetWorkspaceAppByAgentIDAndSlugParams struct {
|
|
AgentID uuid.UUID `db:"agent_id" json:"agent_id"`
|
|
Slug string `db:"slug" json:"slug"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetWorkspaceAppByAgentIDAndSlug(ctx context.Context, arg GetWorkspaceAppByAgentIDAndSlugParams) (WorkspaceApp, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceAppByAgentIDAndSlug, arg.AgentID, arg.Slug)
|
|
var i WorkspaceApp
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.AgentID,
|
|
&i.DisplayName,
|
|
&i.Icon,
|
|
&i.Command,
|
|
&i.Url,
|
|
&i.HealthcheckUrl,
|
|
&i.HealthcheckInterval,
|
|
&i.HealthcheckThreshold,
|
|
&i.Health,
|
|
&i.Subdomain,
|
|
&i.SharingLevel,
|
|
&i.Slug,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceAppsByAgentID = `-- name: GetWorkspaceAppsByAgentID :many
|
|
SELECT id, created_at, agent_id, display_name, icon, command, url, healthcheck_url, healthcheck_interval, healthcheck_threshold, health, subdomain, sharing_level, slug FROM workspace_apps WHERE agent_id = $1 ORDER BY slug ASC
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceAppsByAgentID(ctx context.Context, agentID uuid.UUID) ([]WorkspaceApp, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceAppsByAgentID, agentID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceApp
|
|
for rows.Next() {
|
|
var i WorkspaceApp
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.AgentID,
|
|
&i.DisplayName,
|
|
&i.Icon,
|
|
&i.Command,
|
|
&i.Url,
|
|
&i.HealthcheckUrl,
|
|
&i.HealthcheckInterval,
|
|
&i.HealthcheckThreshold,
|
|
&i.Health,
|
|
&i.Subdomain,
|
|
&i.SharingLevel,
|
|
&i.Slug,
|
|
); 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 getWorkspaceAppsByAgentIDs = `-- name: GetWorkspaceAppsByAgentIDs :many
|
|
SELECT id, created_at, agent_id, display_name, icon, command, url, healthcheck_url, healthcheck_interval, healthcheck_threshold, health, subdomain, sharing_level, slug FROM workspace_apps WHERE agent_id = ANY($1 :: uuid [ ]) ORDER BY slug ASC
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceAppsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceApp, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceAppsByAgentIDs, pq.Array(ids))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceApp
|
|
for rows.Next() {
|
|
var i WorkspaceApp
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.AgentID,
|
|
&i.DisplayName,
|
|
&i.Icon,
|
|
&i.Command,
|
|
&i.Url,
|
|
&i.HealthcheckUrl,
|
|
&i.HealthcheckInterval,
|
|
&i.HealthcheckThreshold,
|
|
&i.Health,
|
|
&i.Subdomain,
|
|
&i.SharingLevel,
|
|
&i.Slug,
|
|
); 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 getWorkspaceAppsCreatedAfter = `-- name: GetWorkspaceAppsCreatedAfter :many
|
|
SELECT id, created_at, agent_id, display_name, icon, command, url, healthcheck_url, healthcheck_interval, healthcheck_threshold, health, subdomain, sharing_level, slug FROM workspace_apps WHERE created_at > $1 ORDER BY slug ASC
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceAppsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceApp, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceAppsCreatedAfter, createdAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceApp
|
|
for rows.Next() {
|
|
var i WorkspaceApp
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.AgentID,
|
|
&i.DisplayName,
|
|
&i.Icon,
|
|
&i.Command,
|
|
&i.Url,
|
|
&i.HealthcheckUrl,
|
|
&i.HealthcheckInterval,
|
|
&i.HealthcheckThreshold,
|
|
&i.Health,
|
|
&i.Subdomain,
|
|
&i.SharingLevel,
|
|
&i.Slug,
|
|
); 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 insertWorkspaceApp = `-- name: InsertWorkspaceApp :one
|
|
INSERT INTO
|
|
workspace_apps (
|
|
id,
|
|
created_at,
|
|
agent_id,
|
|
slug,
|
|
display_name,
|
|
icon,
|
|
command,
|
|
url,
|
|
subdomain,
|
|
sharing_level,
|
|
healthcheck_url,
|
|
healthcheck_interval,
|
|
healthcheck_threshold,
|
|
health
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) RETURNING id, created_at, agent_id, display_name, icon, command, url, healthcheck_url, healthcheck_interval, healthcheck_threshold, health, subdomain, sharing_level, slug
|
|
`
|
|
|
|
type InsertWorkspaceAppParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
AgentID uuid.UUID `db:"agent_id" json:"agent_id"`
|
|
Slug string `db:"slug" json:"slug"`
|
|
DisplayName string `db:"display_name" json:"display_name"`
|
|
Icon string `db:"icon" json:"icon"`
|
|
Command sql.NullString `db:"command" json:"command"`
|
|
Url sql.NullString `db:"url" json:"url"`
|
|
Subdomain bool `db:"subdomain" json:"subdomain"`
|
|
SharingLevel AppSharingLevel `db:"sharing_level" json:"sharing_level"`
|
|
HealthcheckUrl string `db:"healthcheck_url" json:"healthcheck_url"`
|
|
HealthcheckInterval int32 `db:"healthcheck_interval" json:"healthcheck_interval"`
|
|
HealthcheckThreshold int32 `db:"healthcheck_threshold" json:"healthcheck_threshold"`
|
|
Health WorkspaceAppHealth `db:"health" json:"health"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertWorkspaceApp(ctx context.Context, arg InsertWorkspaceAppParams) (WorkspaceApp, error) {
|
|
row := q.db.QueryRowContext(ctx, insertWorkspaceApp,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.AgentID,
|
|
arg.Slug,
|
|
arg.DisplayName,
|
|
arg.Icon,
|
|
arg.Command,
|
|
arg.Url,
|
|
arg.Subdomain,
|
|
arg.SharingLevel,
|
|
arg.HealthcheckUrl,
|
|
arg.HealthcheckInterval,
|
|
arg.HealthcheckThreshold,
|
|
arg.Health,
|
|
)
|
|
var i WorkspaceApp
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.AgentID,
|
|
&i.DisplayName,
|
|
&i.Icon,
|
|
&i.Command,
|
|
&i.Url,
|
|
&i.HealthcheckUrl,
|
|
&i.HealthcheckInterval,
|
|
&i.HealthcheckThreshold,
|
|
&i.Health,
|
|
&i.Subdomain,
|
|
&i.SharingLevel,
|
|
&i.Slug,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateWorkspaceAppHealthByID = `-- name: UpdateWorkspaceAppHealthByID :exec
|
|
UPDATE
|
|
workspace_apps
|
|
SET
|
|
health = $2
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateWorkspaceAppHealthByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Health WorkspaceAppHealth `db:"health" json:"health"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateWorkspaceAppHealthByID(ctx context.Context, arg UpdateWorkspaceAppHealthByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateWorkspaceAppHealthByID, arg.ID, arg.Health)
|
|
return err
|
|
}
|
|
|
|
const getLatestWorkspaceBuildByWorkspaceID = `-- name: GetLatestWorkspaceBuildByWorkspaceID :one
|
|
SELECT
|
|
id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
|
|
FROM
|
|
workspace_builds
|
|
WHERE
|
|
workspace_id = $1
|
|
ORDER BY
|
|
build_number desc
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) (WorkspaceBuild, error) {
|
|
row := q.db.QueryRowContext(ctx, getLatestWorkspaceBuildByWorkspaceID, workspaceID)
|
|
var i WorkspaceBuild
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getLatestWorkspaceBuilds = `-- name: GetLatestWorkspaceBuilds :many
|
|
SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason
|
|
FROM (
|
|
SELECT
|
|
workspace_id, MAX(build_number) as max_build_number
|
|
FROM
|
|
workspace_builds
|
|
GROUP BY
|
|
workspace_id
|
|
) m
|
|
JOIN
|
|
workspace_builds wb
|
|
ON m.workspace_id = wb.workspace_id AND m.max_build_number = wb.build_number
|
|
`
|
|
|
|
func (q *sqlQuerier) GetLatestWorkspaceBuilds(ctx context.Context) ([]WorkspaceBuild, error) {
|
|
rows, err := q.db.QueryContext(ctx, getLatestWorkspaceBuilds)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceBuild
|
|
for rows.Next() {
|
|
var i WorkspaceBuild
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
); 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 getLatestWorkspaceBuildsByWorkspaceIDs = `-- name: GetLatestWorkspaceBuildsByWorkspaceIDs :many
|
|
SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason
|
|
FROM (
|
|
SELECT
|
|
workspace_id, MAX(build_number) as max_build_number
|
|
FROM
|
|
workspace_builds
|
|
WHERE
|
|
workspace_id = ANY($1 :: uuid [ ])
|
|
GROUP BY
|
|
workspace_id
|
|
) m
|
|
JOIN
|
|
workspace_builds wb
|
|
ON m.workspace_id = wb.workspace_id AND m.max_build_number = wb.build_number
|
|
`
|
|
|
|
func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceBuild, error) {
|
|
rows, err := q.db.QueryContext(ctx, getLatestWorkspaceBuildsByWorkspaceIDs, pq.Array(ids))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceBuild
|
|
for rows.Next() {
|
|
var i WorkspaceBuild
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
); 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 getWorkspaceBuildByID = `-- name: GetWorkspaceBuildByID :one
|
|
SELECT
|
|
id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
|
|
FROM
|
|
workspace_builds
|
|
WHERE
|
|
id = $1
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (WorkspaceBuild, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceBuildByID, id)
|
|
var i WorkspaceBuild
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceBuildByJobID = `-- name: GetWorkspaceBuildByJobID :one
|
|
SELECT
|
|
id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
|
|
FROM
|
|
workspace_builds
|
|
WHERE
|
|
job_id = $1
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UUID) (WorkspaceBuild, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceBuildByJobID, jobID)
|
|
var i WorkspaceBuild
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceBuildByWorkspaceIDAndBuildNumber = `-- name: GetWorkspaceBuildByWorkspaceIDAndBuildNumber :one
|
|
SELECT
|
|
id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
|
|
FROM
|
|
workspace_builds
|
|
WHERE
|
|
workspace_id = $1
|
|
AND build_number = $2
|
|
`
|
|
|
|
type GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams struct {
|
|
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
|
BuildNumber int32 `db:"build_number" json:"build_number"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx context.Context, arg GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams) (WorkspaceBuild, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceBuildByWorkspaceIDAndBuildNumber, arg.WorkspaceID, arg.BuildNumber)
|
|
var i WorkspaceBuild
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceBuildsByWorkspaceID = `-- name: GetWorkspaceBuildsByWorkspaceID :many
|
|
SELECT
|
|
id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
|
|
FROM
|
|
workspace_builds
|
|
WHERE
|
|
workspace_builds.workspace_id = $1
|
|
AND workspace_builds.created_at > $2
|
|
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
|
|
-- duplicating or missing data.
|
|
WHEN $3 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN (
|
|
-- The pagination cursor is the last ID of the previous page.
|
|
-- The query is ordered by the build_number field, so select all
|
|
-- rows after the cursor.
|
|
build_number > (
|
|
SELECT
|
|
build_number
|
|
FROM
|
|
workspace_builds
|
|
WHERE
|
|
id = $3
|
|
)
|
|
)
|
|
ELSE true
|
|
END
|
|
ORDER BY
|
|
build_number desc OFFSET $4
|
|
LIMIT
|
|
-- A null limit means "no limit", so 0 means return all
|
|
NULLIF($5 :: int, 0)
|
|
`
|
|
|
|
type GetWorkspaceBuildsByWorkspaceIDParams struct {
|
|
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
|
Since time.Time `db:"since" json:"since"`
|
|
AfterID uuid.UUID `db:"after_id" json:"after_id"`
|
|
OffsetOpt int32 `db:"offset_opt" json:"offset_opt"`
|
|
LimitOpt int32 `db:"limit_opt" json:"limit_opt"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetWorkspaceBuildsByWorkspaceID(ctx context.Context, arg GetWorkspaceBuildsByWorkspaceIDParams) ([]WorkspaceBuild, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceBuildsByWorkspaceID,
|
|
arg.WorkspaceID,
|
|
arg.Since,
|
|
arg.AfterID,
|
|
arg.OffsetOpt,
|
|
arg.LimitOpt,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceBuild
|
|
for rows.Next() {
|
|
var i WorkspaceBuild
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
); 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 getWorkspaceBuildsCreatedAfter = `-- name: GetWorkspaceBuildsCreatedAfter :many
|
|
SELECT id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason FROM workspace_builds WHERE created_at > $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceBuild, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceBuildsCreatedAfter, createdAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceBuild
|
|
for rows.Next() {
|
|
var i WorkspaceBuild
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
); 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 insertWorkspaceBuild = `-- name: InsertWorkspaceBuild :one
|
|
INSERT INTO
|
|
workspace_builds (
|
|
id,
|
|
created_at,
|
|
updated_at,
|
|
workspace_id,
|
|
template_version_id,
|
|
"build_number",
|
|
transition,
|
|
initiator_id,
|
|
job_id,
|
|
provisioner_state,
|
|
deadline,
|
|
reason
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
|
|
`
|
|
|
|
type InsertWorkspaceBuildParams 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"`
|
|
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
|
TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
|
|
BuildNumber int32 `db:"build_number" json:"build_number"`
|
|
Transition WorkspaceTransition `db:"transition" json:"transition"`
|
|
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
|
|
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
|
ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
|
|
Deadline time.Time `db:"deadline" json:"deadline"`
|
|
Reason BuildReason `db:"reason" json:"reason"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) (WorkspaceBuild, error) {
|
|
row := q.db.QueryRowContext(ctx, insertWorkspaceBuild,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.WorkspaceID,
|
|
arg.TemplateVersionID,
|
|
arg.BuildNumber,
|
|
arg.Transition,
|
|
arg.InitiatorID,
|
|
arg.JobID,
|
|
arg.ProvisionerState,
|
|
arg.Deadline,
|
|
arg.Reason,
|
|
)
|
|
var i WorkspaceBuild
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateWorkspaceBuildByID = `-- name: UpdateWorkspaceBuildByID :one
|
|
UPDATE
|
|
workspace_builds
|
|
SET
|
|
updated_at = $2,
|
|
provisioner_state = $3,
|
|
deadline = $4
|
|
WHERE
|
|
id = $1 RETURNING id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
|
|
`
|
|
|
|
type UpdateWorkspaceBuildByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
|
ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
|
|
Deadline time.Time `db:"deadline" json:"deadline"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateWorkspaceBuildByID(ctx context.Context, arg UpdateWorkspaceBuildByIDParams) (WorkspaceBuild, error) {
|
|
row := q.db.QueryRowContext(ctx, updateWorkspaceBuildByID,
|
|
arg.ID,
|
|
arg.UpdatedAt,
|
|
arg.ProvisionerState,
|
|
arg.Deadline,
|
|
)
|
|
var i WorkspaceBuild
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.WorkspaceID,
|
|
&i.TemplateVersionID,
|
|
&i.BuildNumber,
|
|
&i.Transition,
|
|
&i.InitiatorID,
|
|
&i.ProvisionerState,
|
|
&i.JobID,
|
|
&i.Deadline,
|
|
&i.Reason,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceResourceByID = `-- name: GetWorkspaceResourceByID :one
|
|
SELECT
|
|
id, created_at, job_id, transition, type, name, hide, icon, instance_type
|
|
FROM
|
|
workspace_resources
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceResourceByID(ctx context.Context, id uuid.UUID) (WorkspaceResource, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceResourceByID, id)
|
|
var i WorkspaceResource
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.JobID,
|
|
&i.Transition,
|
|
&i.Type,
|
|
&i.Name,
|
|
&i.Hide,
|
|
&i.Icon,
|
|
&i.InstanceType,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceResourceMetadataByResourceID = `-- name: GetWorkspaceResourceMetadataByResourceID :many
|
|
SELECT
|
|
workspace_resource_id, key, value, sensitive
|
|
FROM
|
|
workspace_resource_metadata
|
|
WHERE
|
|
workspace_resource_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceResourceMetadataByResourceID(ctx context.Context, workspaceResourceID uuid.UUID) ([]WorkspaceResourceMetadatum, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceResourceMetadataByResourceID, workspaceResourceID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceResourceMetadatum
|
|
for rows.Next() {
|
|
var i WorkspaceResourceMetadatum
|
|
if err := rows.Scan(
|
|
&i.WorkspaceResourceID,
|
|
&i.Key,
|
|
&i.Value,
|
|
&i.Sensitive,
|
|
); 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 getWorkspaceResourceMetadataByResourceIDs = `-- name: GetWorkspaceResourceMetadataByResourceIDs :many
|
|
SELECT
|
|
workspace_resource_id, key, value, sensitive
|
|
FROM
|
|
workspace_resource_metadata
|
|
WHERE
|
|
workspace_resource_id = ANY($1 :: uuid [ ])
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceResourceMetadataByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceResourceMetadatum, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceResourceMetadataByResourceIDs, pq.Array(ids))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceResourceMetadatum
|
|
for rows.Next() {
|
|
var i WorkspaceResourceMetadatum
|
|
if err := rows.Scan(
|
|
&i.WorkspaceResourceID,
|
|
&i.Key,
|
|
&i.Value,
|
|
&i.Sensitive,
|
|
); 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 getWorkspaceResourceMetadataCreatedAfter = `-- name: GetWorkspaceResourceMetadataCreatedAfter :many
|
|
SELECT workspace_resource_id, key, value, sensitive FROM workspace_resource_metadata WHERE workspace_resource_id = ANY(
|
|
SELECT id FROM workspace_resources WHERE created_at > $1
|
|
)
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceResourceMetadataCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceResourceMetadatum, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceResourceMetadataCreatedAfter, createdAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceResourceMetadatum
|
|
for rows.Next() {
|
|
var i WorkspaceResourceMetadatum
|
|
if err := rows.Scan(
|
|
&i.WorkspaceResourceID,
|
|
&i.Key,
|
|
&i.Value,
|
|
&i.Sensitive,
|
|
); 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 getWorkspaceResourcesByJobID = `-- name: GetWorkspaceResourcesByJobID :many
|
|
SELECT
|
|
id, created_at, job_id, transition, type, name, hide, icon, instance_type
|
|
FROM
|
|
workspace_resources
|
|
WHERE
|
|
job_id = $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceResourcesByJobID(ctx context.Context, jobID uuid.UUID) ([]WorkspaceResource, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceResourcesByJobID, jobID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceResource
|
|
for rows.Next() {
|
|
var i WorkspaceResource
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.JobID,
|
|
&i.Transition,
|
|
&i.Type,
|
|
&i.Name,
|
|
&i.Hide,
|
|
&i.Icon,
|
|
&i.InstanceType,
|
|
); 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 getWorkspaceResourcesByJobIDs = `-- name: GetWorkspaceResourcesByJobIDs :many
|
|
SELECT
|
|
id, created_at, job_id, transition, type, name, hide, icon, instance_type
|
|
FROM
|
|
workspace_resources
|
|
WHERE
|
|
job_id = ANY($1 :: uuid [ ])
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceResourcesByJobIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceResource, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceResourcesByJobIDs, pq.Array(ids))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceResource
|
|
for rows.Next() {
|
|
var i WorkspaceResource
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.JobID,
|
|
&i.Transition,
|
|
&i.Type,
|
|
&i.Name,
|
|
&i.Hide,
|
|
&i.Icon,
|
|
&i.InstanceType,
|
|
); 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 getWorkspaceResourcesCreatedAfter = `-- name: GetWorkspaceResourcesCreatedAfter :many
|
|
SELECT id, created_at, job_id, transition, type, name, hide, icon, instance_type FROM workspace_resources WHERE created_at > $1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceResource, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceResourcesCreatedAfter, createdAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WorkspaceResource
|
|
for rows.Next() {
|
|
var i WorkspaceResource
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.JobID,
|
|
&i.Transition,
|
|
&i.Type,
|
|
&i.Name,
|
|
&i.Hide,
|
|
&i.Icon,
|
|
&i.InstanceType,
|
|
); 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 insertWorkspaceResource = `-- name: InsertWorkspaceResource :one
|
|
INSERT INTO
|
|
workspace_resources (id, created_at, job_id, transition, type, name, hide, icon, instance_type)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, created_at, job_id, transition, type, name, hide, icon, instance_type
|
|
`
|
|
|
|
type InsertWorkspaceResourceParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
|
Transition WorkspaceTransition `db:"transition" json:"transition"`
|
|
Type string `db:"type" json:"type"`
|
|
Name string `db:"name" json:"name"`
|
|
Hide bool `db:"hide" json:"hide"`
|
|
Icon string `db:"icon" json:"icon"`
|
|
InstanceType sql.NullString `db:"instance_type" json:"instance_type"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error) {
|
|
row := q.db.QueryRowContext(ctx, insertWorkspaceResource,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.JobID,
|
|
arg.Transition,
|
|
arg.Type,
|
|
arg.Name,
|
|
arg.Hide,
|
|
arg.Icon,
|
|
arg.InstanceType,
|
|
)
|
|
var i WorkspaceResource
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.JobID,
|
|
&i.Transition,
|
|
&i.Type,
|
|
&i.Name,
|
|
&i.Hide,
|
|
&i.Icon,
|
|
&i.InstanceType,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertWorkspaceResourceMetadata = `-- name: InsertWorkspaceResourceMetadata :one
|
|
INSERT INTO
|
|
workspace_resource_metadata (workspace_resource_id, key, value, sensitive)
|
|
VALUES
|
|
($1, $2, $3, $4) RETURNING workspace_resource_id, key, value, sensitive
|
|
`
|
|
|
|
type InsertWorkspaceResourceMetadataParams struct {
|
|
WorkspaceResourceID uuid.UUID `db:"workspace_resource_id" json:"workspace_resource_id"`
|
|
Key string `db:"key" json:"key"`
|
|
Value sql.NullString `db:"value" json:"value"`
|
|
Sensitive bool `db:"sensitive" json:"sensitive"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertWorkspaceResourceMetadata(ctx context.Context, arg InsertWorkspaceResourceMetadataParams) (WorkspaceResourceMetadatum, error) {
|
|
row := q.db.QueryRowContext(ctx, insertWorkspaceResourceMetadata,
|
|
arg.WorkspaceResourceID,
|
|
arg.Key,
|
|
arg.Value,
|
|
arg.Sensitive,
|
|
)
|
|
var i WorkspaceResourceMetadatum
|
|
err := row.Scan(
|
|
&i.WorkspaceResourceID,
|
|
&i.Key,
|
|
&i.Value,
|
|
&i.Sensitive,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceByID = `-- name: GetWorkspaceByID :one
|
|
SELECT
|
|
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at
|
|
FROM
|
|
workspaces
|
|
WHERE
|
|
id = $1
|
|
LIMIT
|
|
1
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Workspace, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceByID, id)
|
|
var i Workspace
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OwnerID,
|
|
&i.OrganizationID,
|
|
&i.TemplateID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.AutostartSchedule,
|
|
&i.Ttl,
|
|
&i.LastUsedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceByOwnerIDAndName = `-- name: GetWorkspaceByOwnerIDAndName :one
|
|
SELECT
|
|
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at
|
|
FROM
|
|
workspaces
|
|
WHERE
|
|
owner_id = $1
|
|
AND deleted = $2
|
|
AND LOWER("name") = LOWER($3)
|
|
ORDER BY created_at DESC
|
|
`
|
|
|
|
type GetWorkspaceByOwnerIDAndNameParams struct {
|
|
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
Name string `db:"name" json:"name"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWorkspaceByOwnerIDAndNameParams) (Workspace, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceByOwnerIDAndName, arg.OwnerID, arg.Deleted, arg.Name)
|
|
var i Workspace
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OwnerID,
|
|
&i.OrganizationID,
|
|
&i.TemplateID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.AutostartSchedule,
|
|
&i.Ttl,
|
|
&i.LastUsedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWorkspaceCount = `-- name: GetWorkspaceCount :one
|
|
SELECT
|
|
COUNT(*) as count
|
|
FROM
|
|
workspaces
|
|
LEFT JOIN LATERAL (
|
|
SELECT
|
|
workspace_builds.transition,
|
|
provisioner_jobs.started_at,
|
|
provisioner_jobs.updated_at,
|
|
provisioner_jobs.canceled_at,
|
|
provisioner_jobs.completed_at,
|
|
provisioner_jobs.error
|
|
FROM
|
|
workspace_builds
|
|
LEFT JOIN
|
|
provisioner_jobs
|
|
ON
|
|
provisioner_jobs.id = workspace_builds.job_id
|
|
WHERE
|
|
workspace_builds.workspace_id = workspaces.id
|
|
ORDER BY
|
|
build_number DESC
|
|
LIMIT
|
|
1
|
|
) latest_build ON TRUE
|
|
WHERE
|
|
-- Optionally include deleted workspaces
|
|
workspaces.deleted = $1
|
|
AND CASE
|
|
WHEN $2 :: text != '' THEN
|
|
CASE
|
|
WHEN $2 = 'pending' THEN
|
|
latest_build.started_at IS NULL
|
|
WHEN $2 = 'starting' THEN
|
|
latest_build.started_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.completed_at IS NULL AND
|
|
latest_build.updated_at - INTERVAL '30 seconds' < NOW() AND
|
|
latest_build.transition = 'start'::workspace_transition
|
|
|
|
WHEN $2 = 'running' THEN
|
|
latest_build.completed_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.error IS NULL AND
|
|
latest_build.transition = 'start'::workspace_transition
|
|
|
|
WHEN $2 = 'stopping' THEN
|
|
latest_build.started_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.completed_at IS NULL AND
|
|
latest_build.updated_at - INTERVAL '30 seconds' < NOW() AND
|
|
latest_build.transition = 'stop'::workspace_transition
|
|
|
|
WHEN $2 = 'stopped' THEN
|
|
latest_build.completed_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.error IS NULL AND
|
|
latest_build.transition = 'stop'::workspace_transition
|
|
|
|
WHEN $2 = 'failed' THEN
|
|
(latest_build.canceled_at IS NOT NULL AND
|
|
latest_build.error IS NOT NULL) OR
|
|
(latest_build.completed_at IS NOT NULL AND
|
|
latest_build.error IS NOT NULL)
|
|
|
|
WHEN $2 = 'canceling' THEN
|
|
latest_build.canceled_at IS NOT NULL AND
|
|
latest_build.completed_at IS NULL
|
|
|
|
WHEN $2 = 'canceled' THEN
|
|
latest_build.canceled_at IS NOT NULL AND
|
|
latest_build.completed_at IS NOT NULL
|
|
|
|
WHEN $2 = 'deleted' THEN
|
|
latest_build.started_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.completed_at IS NOT NULL AND
|
|
latest_build.updated_at - INTERVAL '30 seconds' < NOW() AND
|
|
latest_build.transition = 'delete'::workspace_transition
|
|
|
|
WHEN $2 = 'deleting' THEN
|
|
latest_build.completed_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.error IS NULL AND
|
|
latest_build.transition = 'delete'::workspace_transition
|
|
|
|
ELSE
|
|
true
|
|
END
|
|
ELSE true
|
|
END
|
|
-- Filter by owner_id
|
|
AND CASE
|
|
WHEN $3 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
|
|
owner_id = $3
|
|
ELSE true
|
|
END
|
|
-- Filter by owner_name
|
|
AND CASE
|
|
WHEN $4 :: text != '' THEN
|
|
owner_id = (SELECT id FROM users WHERE lower(username) = lower($4) AND deleted = false)
|
|
ELSE true
|
|
END
|
|
-- Filter by template_name
|
|
-- There can be more than 1 template with the same name across organizations.
|
|
-- Use the organization filter to restrict to 1 org if needed.
|
|
AND CASE
|
|
WHEN $5 :: text != '' THEN
|
|
template_id = ANY(SELECT id FROM templates WHERE lower(name) = lower($5) AND deleted = false)
|
|
ELSE true
|
|
END
|
|
-- Filter by template_ids
|
|
AND CASE
|
|
WHEN array_length($6 :: uuid[], 1) > 0 THEN
|
|
template_id = ANY($6)
|
|
ELSE true
|
|
END
|
|
-- Filter by name, matching on substring
|
|
AND CASE
|
|
WHEN $7 :: text != '' THEN
|
|
name ILIKE '%' || $7 || '%'
|
|
ELSE true
|
|
END
|
|
-- Authorize Filter clause will be injected below in GetAuthorizedWorkspaceCount
|
|
-- @authorize_filter
|
|
`
|
|
|
|
type GetWorkspaceCountParams struct {
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
Status string `db:"status" json:"status"`
|
|
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
|
OwnerUsername string `db:"owner_username" json:"owner_username"`
|
|
TemplateName string `db:"template_name" json:"template_name"`
|
|
TemplateIds []uuid.UUID `db:"template_ids" json:"template_ids"`
|
|
Name string `db:"name" json:"name"`
|
|
}
|
|
|
|
// this duplicates the filtering in GetWorkspaces
|
|
func (q *sqlQuerier) GetWorkspaceCount(ctx context.Context, arg GetWorkspaceCountParams) (int64, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceCount,
|
|
arg.Deleted,
|
|
arg.Status,
|
|
arg.OwnerID,
|
|
arg.OwnerUsername,
|
|
arg.TemplateName,
|
|
pq.Array(arg.TemplateIds),
|
|
arg.Name,
|
|
)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const getWorkspaceCountByUserID = `-- name: GetWorkspaceCountByUserID :one
|
|
SELECT
|
|
COUNT(id)
|
|
FROM
|
|
workspaces
|
|
WHERE
|
|
owner_id = $1
|
|
-- Ignore deleted workspaces
|
|
AND deleted != true
|
|
`
|
|
|
|
func (q *sqlQuerier) GetWorkspaceCountByUserID(ctx context.Context, ownerID uuid.UUID) (int64, error) {
|
|
row := q.db.QueryRowContext(ctx, getWorkspaceCountByUserID, ownerID)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const getWorkspaceOwnerCountsByTemplateIDs = `-- name: GetWorkspaceOwnerCountsByTemplateIDs :many
|
|
SELECT
|
|
template_id,
|
|
COUNT(DISTINCT owner_id)
|
|
FROM
|
|
workspaces
|
|
WHERE
|
|
template_id = ANY($1 :: uuid [ ])
|
|
-- Ignore deleted workspaces
|
|
AND deleted != true
|
|
GROUP BY
|
|
template_id
|
|
`
|
|
|
|
type GetWorkspaceOwnerCountsByTemplateIDsRow struct {
|
|
TemplateID uuid.UUID `db:"template_id" json:"template_id"`
|
|
Count int64 `db:"count" json:"count"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetWorkspaceOwnerCountsByTemplateIDs(ctx context.Context, ids []uuid.UUID) ([]GetWorkspaceOwnerCountsByTemplateIDsRow, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaceOwnerCountsByTemplateIDs, pq.Array(ids))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetWorkspaceOwnerCountsByTemplateIDsRow
|
|
for rows.Next() {
|
|
var i GetWorkspaceOwnerCountsByTemplateIDsRow
|
|
if err := rows.Scan(&i.TemplateID, &i.Count); 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 getWorkspaces = `-- name: GetWorkspaces :many
|
|
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
|
|
FROM
|
|
workspaces
|
|
LEFT JOIN LATERAL (
|
|
SELECT
|
|
workspace_builds.transition,
|
|
provisioner_jobs.started_at,
|
|
provisioner_jobs.updated_at,
|
|
provisioner_jobs.canceled_at,
|
|
provisioner_jobs.completed_at,
|
|
provisioner_jobs.error
|
|
FROM
|
|
workspace_builds
|
|
LEFT JOIN
|
|
provisioner_jobs
|
|
ON
|
|
provisioner_jobs.id = workspace_builds.job_id
|
|
WHERE
|
|
workspace_builds.workspace_id = workspaces.id
|
|
ORDER BY
|
|
build_number DESC
|
|
LIMIT
|
|
1
|
|
) latest_build ON TRUE
|
|
WHERE
|
|
-- Optionally include deleted workspaces
|
|
workspaces.deleted = $1
|
|
AND CASE
|
|
WHEN $2 :: text != '' THEN
|
|
CASE
|
|
WHEN $2 = 'pending' THEN
|
|
latest_build.started_at IS NULL
|
|
WHEN $2 = 'starting' THEN
|
|
latest_build.started_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.completed_at IS NULL AND
|
|
latest_build.updated_at - INTERVAL '30 seconds' < NOW() AND
|
|
latest_build.transition = 'start'::workspace_transition
|
|
|
|
WHEN $2 = 'running' THEN
|
|
latest_build.completed_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.error IS NULL AND
|
|
latest_build.transition = 'start'::workspace_transition
|
|
|
|
WHEN $2 = 'stopping' THEN
|
|
latest_build.started_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.completed_at IS NULL AND
|
|
latest_build.updated_at - INTERVAL '30 seconds' < NOW() AND
|
|
latest_build.transition = 'stop'::workspace_transition
|
|
|
|
WHEN $2 = 'stopped' THEN
|
|
latest_build.completed_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.error IS NULL AND
|
|
latest_build.transition = 'stop'::workspace_transition
|
|
|
|
WHEN $2 = 'failed' THEN
|
|
(latest_build.canceled_at IS NOT NULL AND
|
|
latest_build.error IS NOT NULL) OR
|
|
(latest_build.completed_at IS NOT NULL AND
|
|
latest_build.error IS NOT NULL)
|
|
|
|
WHEN $2 = 'canceling' THEN
|
|
latest_build.canceled_at IS NOT NULL AND
|
|
latest_build.completed_at IS NULL
|
|
|
|
WHEN $2 = 'canceled' THEN
|
|
latest_build.canceled_at IS NOT NULL AND
|
|
latest_build.completed_at IS NOT NULL
|
|
|
|
WHEN $2 = 'deleted' THEN
|
|
latest_build.started_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.completed_at IS NOT NULL AND
|
|
latest_build.updated_at - INTERVAL '30 seconds' < NOW() AND
|
|
latest_build.transition = 'delete'::workspace_transition
|
|
|
|
WHEN $2 = 'deleting' THEN
|
|
latest_build.completed_at IS NOT NULL AND
|
|
latest_build.canceled_at IS NULL AND
|
|
latest_build.error IS NULL AND
|
|
latest_build.transition = 'delete'::workspace_transition
|
|
|
|
ELSE
|
|
true
|
|
END
|
|
ELSE true
|
|
END
|
|
-- Filter by owner_id
|
|
AND CASE
|
|
WHEN $3 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
|
|
owner_id = $3
|
|
ELSE true
|
|
END
|
|
-- Filter by owner_name
|
|
AND CASE
|
|
WHEN $4 :: text != '' THEN
|
|
owner_id = (SELECT id FROM users WHERE lower(username) = lower($4) AND deleted = false)
|
|
ELSE true
|
|
END
|
|
-- Filter by template_name
|
|
-- There can be more than 1 template with the same name across organizations.
|
|
-- Use the organization filter to restrict to 1 org if needed.
|
|
AND CASE
|
|
WHEN $5 :: text != '' THEN
|
|
template_id = ANY(SELECT id FROM templates WHERE lower(name) = lower($5) AND deleted = false)
|
|
ELSE true
|
|
END
|
|
-- Filter by template_ids
|
|
AND CASE
|
|
WHEN array_length($6 :: uuid[], 1) > 0 THEN
|
|
template_id = ANY($6)
|
|
ELSE true
|
|
END
|
|
-- Filter by name, matching on substring
|
|
AND CASE
|
|
WHEN $7 :: text != '' THEN
|
|
name ILIKE '%' || $7 || '%'
|
|
ELSE true
|
|
END
|
|
-- Authorize Filter clause will be injected below in GetAuthorizedWorkspaces
|
|
-- @authorize_filter
|
|
ORDER BY
|
|
last_used_at DESC
|
|
LIMIT
|
|
CASE
|
|
WHEN $9 :: integer > 0 THEN
|
|
$9
|
|
END
|
|
OFFSET
|
|
$8
|
|
`
|
|
|
|
type GetWorkspacesParams struct {
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
Status string `db:"status" json:"status"`
|
|
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
|
OwnerUsername string `db:"owner_username" json:"owner_username"`
|
|
TemplateName string `db:"template_name" json:"template_name"`
|
|
TemplateIds []uuid.UUID `db:"template_ids" json:"template_ids"`
|
|
Name string `db:"name" json:"name"`
|
|
Offset int32 `db:"offset_" json:"offset_"`
|
|
Limit int32 `db:"limit_" json:"limit_"`
|
|
}
|
|
|
|
func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams) ([]Workspace, error) {
|
|
rows, err := q.db.QueryContext(ctx, getWorkspaces,
|
|
arg.Deleted,
|
|
arg.Status,
|
|
arg.OwnerID,
|
|
arg.OwnerUsername,
|
|
arg.TemplateName,
|
|
pq.Array(arg.TemplateIds),
|
|
arg.Name,
|
|
arg.Offset,
|
|
arg.Limit,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []Workspace
|
|
for rows.Next() {
|
|
var i Workspace
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OwnerID,
|
|
&i.OrganizationID,
|
|
&i.TemplateID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.AutostartSchedule,
|
|
&i.Ttl,
|
|
&i.LastUsedAt,
|
|
); 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 insertWorkspace = `-- name: InsertWorkspace :one
|
|
INSERT INTO
|
|
workspaces (
|
|
id,
|
|
created_at,
|
|
updated_at,
|
|
owner_id,
|
|
organization_id,
|
|
template_id,
|
|
name,
|
|
autostart_schedule,
|
|
ttl
|
|
)
|
|
VALUES
|
|
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at
|
|
`
|
|
|
|
type InsertWorkspaceParams 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"`
|
|
Name string `db:"name" json:"name"`
|
|
AutostartSchedule sql.NullString `db:"autostart_schedule" json:"autostart_schedule"`
|
|
Ttl sql.NullInt64 `db:"ttl" json:"ttl"`
|
|
}
|
|
|
|
func (q *sqlQuerier) InsertWorkspace(ctx context.Context, arg InsertWorkspaceParams) (Workspace, error) {
|
|
row := q.db.QueryRowContext(ctx, insertWorkspace,
|
|
arg.ID,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
arg.OwnerID,
|
|
arg.OrganizationID,
|
|
arg.TemplateID,
|
|
arg.Name,
|
|
arg.AutostartSchedule,
|
|
arg.Ttl,
|
|
)
|
|
var i Workspace
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OwnerID,
|
|
&i.OrganizationID,
|
|
&i.TemplateID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.AutostartSchedule,
|
|
&i.Ttl,
|
|
&i.LastUsedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateWorkspace = `-- name: UpdateWorkspace :one
|
|
UPDATE
|
|
workspaces
|
|
SET
|
|
name = $2
|
|
WHERE
|
|
id = $1
|
|
AND deleted = false
|
|
RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at
|
|
`
|
|
|
|
type UpdateWorkspaceParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Name string `db:"name" json:"name"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateWorkspace(ctx context.Context, arg UpdateWorkspaceParams) (Workspace, error) {
|
|
row := q.db.QueryRowContext(ctx, updateWorkspace, arg.ID, arg.Name)
|
|
var i Workspace
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.OwnerID,
|
|
&i.OrganizationID,
|
|
&i.TemplateID,
|
|
&i.Deleted,
|
|
&i.Name,
|
|
&i.AutostartSchedule,
|
|
&i.Ttl,
|
|
&i.LastUsedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateWorkspaceAutostart = `-- name: UpdateWorkspaceAutostart :exec
|
|
UPDATE
|
|
workspaces
|
|
SET
|
|
autostart_schedule = $2
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateWorkspaceAutostartParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
AutostartSchedule sql.NullString `db:"autostart_schedule" json:"autostart_schedule"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateWorkspaceAutostart(ctx context.Context, arg UpdateWorkspaceAutostartParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateWorkspaceAutostart, arg.ID, arg.AutostartSchedule)
|
|
return err
|
|
}
|
|
|
|
const updateWorkspaceDeletedByID = `-- name: UpdateWorkspaceDeletedByID :exec
|
|
UPDATE
|
|
workspaces
|
|
SET
|
|
deleted = $2
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateWorkspaceDeletedByIDParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Deleted bool `db:"deleted" json:"deleted"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateWorkspaceDeletedByID(ctx context.Context, arg UpdateWorkspaceDeletedByIDParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateWorkspaceDeletedByID, arg.ID, arg.Deleted)
|
|
return err
|
|
}
|
|
|
|
const updateWorkspaceLastUsedAt = `-- name: UpdateWorkspaceLastUsedAt :exec
|
|
UPDATE
|
|
workspaces
|
|
SET
|
|
last_used_at = $2
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateWorkspaceLastUsedAtParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
LastUsedAt time.Time `db:"last_used_at" json:"last_used_at"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateWorkspaceLastUsedAt(ctx context.Context, arg UpdateWorkspaceLastUsedAtParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateWorkspaceLastUsedAt, arg.ID, arg.LastUsedAt)
|
|
return err
|
|
}
|
|
|
|
const updateWorkspaceTTL = `-- name: UpdateWorkspaceTTL :exec
|
|
UPDATE
|
|
workspaces
|
|
SET
|
|
ttl = $2
|
|
WHERE
|
|
id = $1
|
|
`
|
|
|
|
type UpdateWorkspaceTTLParams struct {
|
|
ID uuid.UUID `db:"id" json:"id"`
|
|
Ttl sql.NullInt64 `db:"ttl" json:"ttl"`
|
|
}
|
|
|
|
func (q *sqlQuerier) UpdateWorkspaceTTL(ctx context.Context, arg UpdateWorkspaceTTLParams) error {
|
|
_, err := q.db.ExecContext(ctx, updateWorkspaceTTL, arg.ID, arg.Ttl)
|
|
return err
|
|
}
|