mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: add "user_configs" db table (#16564)
This commit is contained in:
@@ -150,14 +150,13 @@ func ReducedUser(user database.User) codersdk.ReducedUser {
|
||||
Username: user.Username,
|
||||
AvatarURL: user.AvatarURL,
|
||||
},
|
||||
Email: user.Email,
|
||||
Name: user.Name,
|
||||
CreatedAt: user.CreatedAt,
|
||||
UpdatedAt: user.UpdatedAt,
|
||||
LastSeenAt: user.LastSeenAt,
|
||||
Status: codersdk.UserStatus(user.Status),
|
||||
LoginType: codersdk.LoginType(user.LoginType),
|
||||
ThemePreference: user.ThemePreference,
|
||||
Email: user.Email,
|
||||
Name: user.Name,
|
||||
CreatedAt: user.CreatedAt,
|
||||
UpdatedAt: user.UpdatedAt,
|
||||
LastSeenAt: user.LastSeenAt,
|
||||
Status: codersdk.UserStatus(user.Status),
|
||||
LoginType: codersdk.LoginType(user.LoginType),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +175,6 @@ func UserFromGroupMember(member database.GroupMember) database.User {
|
||||
Deleted: member.UserDeleted,
|
||||
LastSeenAt: member.UserLastSeenAt,
|
||||
QuietHoursSchedule: member.UserQuietHoursSchedule,
|
||||
ThemePreference: member.UserThemePreference,
|
||||
Name: member.UserName,
|
||||
GithubComUserID: member.UserGithubComUserID,
|
||||
}
|
||||
|
||||
@@ -2510,6 +2510,17 @@ func (q *querier) GetUserActivityInsights(ctx context.Context, arg database.GetU
|
||||
return q.db.GetUserActivityInsights(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserAppearanceSettings(ctx context.Context, userID uuid.UUID) (string, error) {
|
||||
u, err := q.db.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionReadPersonal, u); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return q.db.GetUserAppearanceSettings(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserByEmailOrUsername(ctx context.Context, arg database.GetUserByEmailOrUsernameParams) (database.User, error) {
|
||||
return fetch(q.log, q.auth, q.db.GetUserByEmailOrUsername)(ctx, arg)
|
||||
}
|
||||
@@ -4021,13 +4032,13 @@ func (q *querier) UpdateTemplateWorkspacesLastUsedAt(ctx context.Context, arg da
|
||||
return fetchAndExec(q.log, q.auth, policy.ActionUpdate, fetch, q.db.UpdateTemplateWorkspacesLastUsedAt)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateUserAppearanceSettings(ctx context.Context, arg database.UpdateUserAppearanceSettingsParams) (database.User, error) {
|
||||
u, err := q.db.GetUserByID(ctx, arg.ID)
|
||||
func (q *querier) UpdateUserAppearanceSettings(ctx context.Context, arg database.UpdateUserAppearanceSettingsParams) (database.UserConfig, error) {
|
||||
u, err := q.db.GetUserByID(ctx, arg.UserID)
|
||||
if err != nil {
|
||||
return database.User{}, err
|
||||
return database.UserConfig{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdatePersonal, u); err != nil {
|
||||
return database.User{}, err
|
||||
return database.UserConfig{}, err
|
||||
}
|
||||
return q.db.UpdateUserAppearanceSettings(ctx, arg)
|
||||
}
|
||||
|
||||
@@ -1522,13 +1522,26 @@ func (s *MethodTestSuite) TestUser() {
|
||||
[]database.GetUserWorkspaceBuildParametersRow{},
|
||||
)
|
||||
}))
|
||||
s.Run("GetUserAppearanceSettings", s.Subtest(func(db database.Store, check *expects) {
|
||||
ctx := context.Background()
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
db.UpdateUserAppearanceSettings(ctx, database.UpdateUserAppearanceSettingsParams{
|
||||
UserID: u.ID,
|
||||
ThemePreference: "light",
|
||||
})
|
||||
check.Args(u.ID).Asserts(u, policy.ActionReadPersonal).Returns("light")
|
||||
}))
|
||||
s.Run("UpdateUserAppearanceSettings", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
uc := database.UserConfig{
|
||||
UserID: u.ID,
|
||||
Key: "theme_preference",
|
||||
Value: "dark",
|
||||
}
|
||||
check.Args(database.UpdateUserAppearanceSettingsParams{
|
||||
ID: u.ID,
|
||||
ThemePreference: u.ThemePreference,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
}).Asserts(u, policy.ActionUpdatePersonal).Returns(u)
|
||||
UserID: u.ID,
|
||||
ThemePreference: uc.Value,
|
||||
}).Asserts(u, policy.ActionUpdatePersonal).Returns(uc)
|
||||
}))
|
||||
s.Run("UpdateUserStatus", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
|
||||
@@ -528,7 +528,6 @@ func GroupMember(t testing.TB, db database.Store, member database.GroupMemberTab
|
||||
UserDeleted: user.Deleted,
|
||||
UserLastSeenAt: user.LastSeenAt,
|
||||
UserQuietHoursSchedule: user.QuietHoursSchedule,
|
||||
UserThemePreference: user.ThemePreference,
|
||||
UserName: user.Name,
|
||||
UserGithubComUserID: user.GithubComUserID,
|
||||
OrganizationID: group.OrganizationID,
|
||||
|
||||
@@ -55,44 +55,45 @@ func New() database.Store {
|
||||
mutex: &sync.RWMutex{},
|
||||
data: &data{
|
||||
apiKeys: make([]database.APIKey, 0),
|
||||
organizationMembers: make([]database.OrganizationMember, 0),
|
||||
organizations: make([]database.Organization, 0),
|
||||
users: make([]database.User, 0),
|
||||
auditLogs: make([]database.AuditLog, 0),
|
||||
customRoles: make([]database.CustomRole, 0),
|
||||
dbcryptKeys: make([]database.DBCryptKey, 0),
|
||||
externalAuthLinks: make([]database.ExternalAuthLink, 0),
|
||||
groups: make([]database.Group, 0),
|
||||
groupMembers: make([]database.GroupMemberTable, 0),
|
||||
auditLogs: make([]database.AuditLog, 0),
|
||||
files: make([]database.File, 0),
|
||||
gitSSHKey: make([]database.GitSSHKey, 0),
|
||||
groups: make([]database.Group, 0),
|
||||
groupMembers: make([]database.GroupMemberTable, 0),
|
||||
licenses: make([]database.License, 0),
|
||||
locks: map[int64]struct{}{},
|
||||
notificationMessages: make([]database.NotificationMessage, 0),
|
||||
notificationPreferences: make([]database.NotificationPreference, 0),
|
||||
InboxNotification: make([]database.InboxNotification, 0),
|
||||
organizationMembers: make([]database.OrganizationMember, 0),
|
||||
organizations: make([]database.Organization, 0),
|
||||
inboxNotifications: make([]database.InboxNotification, 0),
|
||||
parameterSchemas: make([]database.ParameterSchema, 0),
|
||||
presets: make([]database.TemplateVersionPreset, 0),
|
||||
presetParameters: make([]database.TemplateVersionPresetParameter, 0),
|
||||
provisionerDaemons: make([]database.ProvisionerDaemon, 0),
|
||||
provisionerKeys: make([]database.ProvisionerKey, 0),
|
||||
workspaceAgents: make([]database.WorkspaceAgent, 0),
|
||||
provisionerJobs: make([]database.ProvisionerJob, 0),
|
||||
provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
|
||||
provisionerKeys: make([]database.ProvisionerKey, 0),
|
||||
runtimeConfig: map[string]string{},
|
||||
telemetryItems: make([]database.TelemetryItem, 0),
|
||||
templateVersions: make([]database.TemplateVersionTable, 0),
|
||||
templates: make([]database.TemplateTable, 0),
|
||||
users: make([]database.User, 0),
|
||||
userConfigs: make([]database.UserConfig, 0),
|
||||
userStatusChanges: make([]database.UserStatusChange, 0),
|
||||
workspaceAgents: make([]database.WorkspaceAgent, 0),
|
||||
workspaceResources: make([]database.WorkspaceResource, 0),
|
||||
workspaceModules: make([]database.WorkspaceModule, 0),
|
||||
workspaceResourceMetadata: make([]database.WorkspaceResourceMetadatum, 0),
|
||||
provisionerJobs: make([]database.ProvisionerJob, 0),
|
||||
templateVersions: make([]database.TemplateVersionTable, 0),
|
||||
templates: make([]database.TemplateTable, 0),
|
||||
workspaceAgentStats: make([]database.WorkspaceAgentStat, 0),
|
||||
workspaceAgentLogs: make([]database.WorkspaceAgentLog, 0),
|
||||
workspaceBuilds: make([]database.WorkspaceBuild, 0),
|
||||
workspaceApps: make([]database.WorkspaceApp, 0),
|
||||
workspaces: make([]database.WorkspaceTable, 0),
|
||||
licenses: make([]database.License, 0),
|
||||
workspaceProxies: make([]database.WorkspaceProxy, 0),
|
||||
customRoles: make([]database.CustomRole, 0),
|
||||
locks: map[int64]struct{}{},
|
||||
runtimeConfig: map[string]string{},
|
||||
userStatusChanges: make([]database.UserStatusChange, 0),
|
||||
telemetryItems: make([]database.TelemetryItem, 0),
|
||||
presets: make([]database.TemplateVersionPreset, 0),
|
||||
presetParameters: make([]database.TemplateVersionPresetParameter, 0),
|
||||
},
|
||||
}
|
||||
// Always start with a default org. Matching migration 198.
|
||||
@@ -207,7 +208,7 @@ type data struct {
|
||||
notificationMessages []database.NotificationMessage
|
||||
notificationPreferences []database.NotificationPreference
|
||||
notificationReportGeneratorLogs []database.NotificationReportGeneratorLog
|
||||
InboxNotification []database.InboxNotification
|
||||
inboxNotifications []database.InboxNotification
|
||||
oauth2ProviderApps []database.OAuth2ProviderApp
|
||||
oauth2ProviderAppSecrets []database.OAuth2ProviderAppSecret
|
||||
oauth2ProviderAppCodes []database.OAuth2ProviderAppCode
|
||||
@@ -224,6 +225,7 @@ type data struct {
|
||||
templateVersionWorkspaceTags []database.TemplateVersionWorkspaceTag
|
||||
templates []database.TemplateTable
|
||||
templateUsageStats []database.TemplateUsageStat
|
||||
userConfigs []database.UserConfig
|
||||
workspaceAgents []database.WorkspaceAgent
|
||||
workspaceAgentMetadata []database.WorkspaceAgentMetadatum
|
||||
workspaceAgentLogs []database.WorkspaceAgentLog
|
||||
@@ -899,7 +901,6 @@ func (q *FakeQuerier) getGroupMemberNoLock(ctx context.Context, userID, groupID
|
||||
UserDeleted: user.Deleted,
|
||||
UserLastSeenAt: user.LastSeenAt,
|
||||
UserQuietHoursSchedule: user.QuietHoursSchedule,
|
||||
UserThemePreference: user.ThemePreference,
|
||||
UserName: user.Name,
|
||||
UserGithubComUserID: user.GithubComUserID,
|
||||
OrganizationID: orgID,
|
||||
@@ -1725,7 +1726,7 @@ func (q *FakeQuerier) CountUnreadInboxNotificationsByUserID(_ context.Context, u
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
var count int64
|
||||
for _, notification := range q.InboxNotification {
|
||||
for _, notification := range q.inboxNotifications {
|
||||
if notification.UserID != userID {
|
||||
continue
|
||||
}
|
||||
@@ -3295,7 +3296,7 @@ func (q *FakeQuerier) GetFilteredInboxNotificationsByUserID(_ context.Context, a
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
notifications := make([]database.InboxNotification, 0)
|
||||
for _, notification := range q.InboxNotification {
|
||||
for _, notification := range q.inboxNotifications {
|
||||
if notification.UserID == arg.UserID {
|
||||
for _, template := range arg.Templates {
|
||||
templateFound := false
|
||||
@@ -3531,7 +3532,7 @@ func (q *FakeQuerier) GetInboxNotificationByID(_ context.Context, id uuid.UUID)
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, notification := range q.InboxNotification {
|
||||
for _, notification := range q.inboxNotifications {
|
||||
if notification.ID == id {
|
||||
return notification, nil
|
||||
}
|
||||
@@ -3545,7 +3546,7 @@ func (q *FakeQuerier) GetInboxNotificationsByUserID(_ context.Context, params da
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
notifications := make([]database.InboxNotification, 0)
|
||||
for _, notification := range q.InboxNotification {
|
||||
for _, notification := range q.inboxNotifications {
|
||||
if notification.UserID == params.UserID {
|
||||
notifications = append(notifications, notification)
|
||||
}
|
||||
@@ -6162,6 +6163,20 @@ func (q *FakeQuerier) GetUserActivityInsights(_ context.Context, arg database.Ge
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetUserAppearanceSettings(_ context.Context, userID uuid.UUID) (string, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, uc := range q.userConfigs {
|
||||
if uc.UserID != userID || uc.Key != "theme_preference" {
|
||||
continue
|
||||
}
|
||||
return uc.Value, nil
|
||||
}
|
||||
|
||||
return "", sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetUserByEmailOrUsername(_ context.Context, arg database.GetUserByEmailOrUsernameParams) (database.User, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.User{}, err
|
||||
@@ -8211,7 +8226,7 @@ func (q *FakeQuerier) InsertInboxNotification(_ context.Context, arg database.In
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
q.InboxNotification = append(q.InboxNotification, notification)
|
||||
q.inboxNotifications = append(q.inboxNotifications, notification)
|
||||
return notification, nil
|
||||
}
|
||||
|
||||
@@ -9938,9 +9953,9 @@ func (q *FakeQuerier) UpdateInboxNotificationReadStatus(_ context.Context, arg d
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for i := range q.InboxNotification {
|
||||
if q.InboxNotification[i].ID == arg.ID {
|
||||
q.InboxNotification[i].ReadAt = arg.ReadAt
|
||||
for i := range q.inboxNotifications {
|
||||
if q.inboxNotifications[i].ID == arg.ID {
|
||||
q.inboxNotifications[i].ReadAt = arg.ReadAt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10454,24 +10469,31 @@ func (q *FakeQuerier) UpdateTemplateWorkspacesLastUsedAt(_ context.Context, arg
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) UpdateUserAppearanceSettings(_ context.Context, arg database.UpdateUserAppearanceSettingsParams) (database.User, error) {
|
||||
func (q *FakeQuerier) UpdateUserAppearanceSettings(_ context.Context, arg database.UpdateUserAppearanceSettingsParams) (database.UserConfig, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
return database.User{}, err
|
||||
return database.UserConfig{}, err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, user := range q.users {
|
||||
if user.ID != arg.ID {
|
||||
for i, uc := range q.userConfigs {
|
||||
if uc.UserID != arg.UserID || uc.Key != "theme_preference" {
|
||||
continue
|
||||
}
|
||||
user.ThemePreference = arg.ThemePreference
|
||||
q.users[index] = user
|
||||
return user, nil
|
||||
uc.Value = arg.ThemePreference
|
||||
q.userConfigs[i] = uc
|
||||
return uc, nil
|
||||
}
|
||||
return database.User{}, sql.ErrNoRows
|
||||
|
||||
uc := database.UserConfig{
|
||||
UserID: arg.UserID,
|
||||
Key: "theme_preference",
|
||||
Value: arg.ThemePreference,
|
||||
}
|
||||
q.userConfigs = append(q.userConfigs, uc)
|
||||
return uc, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) UpdateUserDeletedByID(_ context.Context, id uuid.UUID) error {
|
||||
@@ -12862,7 +12884,6 @@ func (q *FakeQuerier) GetAuthorizedAuditLogsOffset(ctx context.Context, arg data
|
||||
UserLastSeenAt: sql.NullTime{Time: user.LastSeenAt, Valid: userValid},
|
||||
UserLoginType: database.NullLoginType{LoginType: user.LoginType, Valid: userValid},
|
||||
UserDeleted: sql.NullBool{Bool: user.Deleted, Valid: userValid},
|
||||
UserThemePreference: sql.NullString{String: user.ThemePreference, Valid: userValid},
|
||||
UserQuietHoursSchedule: sql.NullString{String: user.QuietHoursSchedule, Valid: userValid},
|
||||
UserStatus: database.NullUserStatus{UserStatus: user.Status, Valid: userValid},
|
||||
UserRoles: user.RBACRoles,
|
||||
|
||||
@@ -1403,6 +1403,13 @@ func (m queryMetricsStore) GetUserActivityInsights(ctx context.Context, arg data
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetUserAppearanceSettings(ctx context.Context, userID uuid.UUID) (string, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetUserAppearanceSettings(ctx, userID)
|
||||
m.queryLatencies.WithLabelValues("GetUserAppearanceSettings").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetUserByEmailOrUsername(ctx context.Context, arg database.GetUserByEmailOrUsernameParams) (database.User, error) {
|
||||
start := time.Now()
|
||||
user, err := m.s.GetUserByEmailOrUsername(ctx, arg)
|
||||
@@ -2551,7 +2558,7 @@ func (m queryMetricsStore) UpdateTemplateWorkspacesLastUsedAt(ctx context.Contex
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) UpdateUserAppearanceSettings(ctx context.Context, arg database.UpdateUserAppearanceSettingsParams) (database.User, error) {
|
||||
func (m queryMetricsStore) UpdateUserAppearanceSettings(ctx context.Context, arg database.UpdateUserAppearanceSettingsParams) (database.UserConfig, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.UpdateUserAppearanceSettings(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("UpdateUserAppearanceSettings").Observe(time.Since(start).Seconds())
|
||||
|
||||
@@ -2932,6 +2932,21 @@ func (mr *MockStoreMockRecorder) GetUserActivityInsights(ctx, arg any) *gomock.C
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserActivityInsights", reflect.TypeOf((*MockStore)(nil).GetUserActivityInsights), ctx, arg)
|
||||
}
|
||||
|
||||
// GetUserAppearanceSettings mocks base method.
|
||||
func (m *MockStore) GetUserAppearanceSettings(ctx context.Context, userID uuid.UUID) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetUserAppearanceSettings", ctx, userID)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetUserAppearanceSettings indicates an expected call of GetUserAppearanceSettings.
|
||||
func (mr *MockStoreMockRecorder) GetUserAppearanceSettings(ctx, userID any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserAppearanceSettings", reflect.TypeOf((*MockStore)(nil).GetUserAppearanceSettings), ctx, userID)
|
||||
}
|
||||
|
||||
// GetUserByEmailOrUsername mocks base method.
|
||||
func (m *MockStore) GetUserByEmailOrUsername(ctx context.Context, arg database.GetUserByEmailOrUsernameParams) (database.User, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -5399,10 +5414,10 @@ func (mr *MockStoreMockRecorder) UpdateTemplateWorkspacesLastUsedAt(ctx, arg any
|
||||
}
|
||||
|
||||
// UpdateUserAppearanceSettings mocks base method.
|
||||
func (m *MockStore) UpdateUserAppearanceSettings(ctx context.Context, arg database.UpdateUserAppearanceSettingsParams) (database.User, error) {
|
||||
func (m *MockStore) UpdateUserAppearanceSettings(ctx context.Context, arg database.UpdateUserAppearanceSettingsParams) (database.UserConfig, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpdateUserAppearanceSettings", ctx, arg)
|
||||
ret0, _ := ret[0].(database.User)
|
||||
ret0, _ := ret[0].(database.UserConfig)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
Generated
+12
-4
@@ -849,7 +849,6 @@ CREATE TABLE users (
|
||||
deleted boolean DEFAULT false NOT NULL,
|
||||
last_seen_at timestamp without time zone DEFAULT '0001-01-01 00:00:00'::timestamp without time zone NOT NULL,
|
||||
quiet_hours_schedule text DEFAULT ''::text NOT NULL,
|
||||
theme_preference text DEFAULT ''::text NOT NULL,
|
||||
name text DEFAULT ''::text NOT NULL,
|
||||
github_com_user_id bigint,
|
||||
hashed_one_time_passcode bytea,
|
||||
@@ -859,8 +858,6 @@ CREATE TABLE users (
|
||||
|
||||
COMMENT ON COLUMN users.quiet_hours_schedule IS 'Daily (!) cron schedule (with optional CRON_TZ) signifying the start of the user''s quiet hours. If empty, the default quiet hours on the instance is used instead.';
|
||||
|
||||
COMMENT ON COLUMN users.theme_preference IS '"" can be interpreted as "the user does not care", falling back to the default theme';
|
||||
|
||||
COMMENT ON COLUMN users.name IS 'Name of the Coder user';
|
||||
|
||||
COMMENT ON COLUMN users.github_com_user_id IS 'The GitHub.com numerical user ID. At time of implementation, this is used to check if the user has starred the Coder repository.';
|
||||
@@ -892,7 +889,6 @@ CREATE VIEW group_members_expanded AS
|
||||
users.deleted AS user_deleted,
|
||||
users.last_seen_at AS user_last_seen_at,
|
||||
users.quiet_hours_schedule AS user_quiet_hours_schedule,
|
||||
users.theme_preference AS user_theme_preference,
|
||||
users.name AS user_name,
|
||||
users.github_com_user_id AS user_github_com_user_id,
|
||||
groups.organization_id,
|
||||
@@ -1547,6 +1543,12 @@ CREATE VIEW template_with_names AS
|
||||
|
||||
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';
|
||||
|
||||
CREATE TABLE user_configs (
|
||||
user_id uuid NOT NULL,
|
||||
key character varying(256) NOT NULL,
|
||||
value text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE user_deleted (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
user_id uuid NOT NULL,
|
||||
@@ -2199,6 +2201,9 @@ ALTER TABLE ONLY template_versions
|
||||
ALTER TABLE ONLY templates
|
||||
ADD CONSTRAINT templates_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY user_configs
|
||||
ADD CONSTRAINT user_configs_pkey PRIMARY KEY (user_id, key);
|
||||
|
||||
ALTER TABLE ONLY user_deleted
|
||||
ADD CONSTRAINT user_deleted_pkey PRIMARY KEY (id);
|
||||
|
||||
@@ -2613,6 +2618,9 @@ ALTER TABLE ONLY templates
|
||||
ALTER TABLE ONLY templates
|
||||
ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY user_configs
|
||||
ADD CONSTRAINT user_configs_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY user_deleted
|
||||
ADD CONSTRAINT user_deleted_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ const (
|
||||
ForeignKeyTemplateVersionsTemplateID ForeignKeyConstraint = "template_versions_template_id_fkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE CASCADE;
|
||||
ForeignKeyTemplatesCreatedBy ForeignKeyConstraint = "templates_created_by_fkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT;
|
||||
ForeignKeyTemplatesOrganizationID ForeignKeyConstraint = "templates_organization_id_fkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserConfigsUserID ForeignKeyConstraint = "user_configs_user_id_fkey" // ALTER TABLE ONLY user_configs ADD CONSTRAINT user_configs_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserDeletedUserID ForeignKeyConstraint = "user_deleted_user_id_fkey" // ALTER TABLE ONLY user_deleted ADD CONSTRAINT user_deleted_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
ForeignKeyUserLinksOauthAccessTokenKeyID ForeignKeyConstraint = "user_links_oauth_access_token_key_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_oauth_access_token_key_id_fkey FOREIGN KEY (oauth_access_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
ForeignKeyUserLinksOauthRefreshTokenKeyID ForeignKeyConstraint = "user_links_oauth_refresh_token_key_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_oauth_refresh_token_key_id_fkey FOREIGN KEY (oauth_refresh_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
-- Put back "theme_preference" column
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS
|
||||
theme_preference text DEFAULT ''::text NOT NULL;
|
||||
|
||||
-- Copy "theme_preference" back to "users"
|
||||
UPDATE users
|
||||
SET theme_preference = (SELECT value
|
||||
FROM user_configs
|
||||
WHERE user_configs.user_id = users.id
|
||||
AND user_configs.key = 'theme_preference');
|
||||
|
||||
-- Drop the "user_configs" table.
|
||||
DROP TABLE user_configs;
|
||||
|
||||
-- Replace "group_members_expanded", and bring back with "theme_preference"
|
||||
DROP VIEW group_members_expanded;
|
||||
-- Taken from 000242_group_members_view.up.sql
|
||||
CREATE VIEW
|
||||
group_members_expanded
|
||||
AS
|
||||
-- If the group is a user made group, then we need to check the group_members table.
|
||||
-- If it is the "Everyone" group, then we need to check the organization_members table.
|
||||
WITH all_members AS (
|
||||
SELECT user_id, group_id FROM group_members
|
||||
UNION
|
||||
SELECT user_id, organization_id AS group_id FROM organization_members
|
||||
)
|
||||
SELECT
|
||||
users.id AS user_id,
|
||||
users.email AS user_email,
|
||||
users.username AS user_username,
|
||||
users.hashed_password AS user_hashed_password,
|
||||
users.created_at AS user_created_at,
|
||||
users.updated_at AS user_updated_at,
|
||||
users.status AS user_status,
|
||||
users.rbac_roles AS user_rbac_roles,
|
||||
users.login_type AS user_login_type,
|
||||
users.avatar_url AS user_avatar_url,
|
||||
users.deleted AS user_deleted,
|
||||
users.last_seen_at AS user_last_seen_at,
|
||||
users.quiet_hours_schedule AS user_quiet_hours_schedule,
|
||||
users.theme_preference AS user_theme_preference,
|
||||
users.name AS user_name,
|
||||
users.github_com_user_id AS user_github_com_user_id,
|
||||
groups.organization_id AS organization_id,
|
||||
groups.name AS group_name,
|
||||
all_members.group_id AS group_id
|
||||
FROM
|
||||
all_members
|
||||
JOIN
|
||||
users ON users.id = all_members.user_id
|
||||
JOIN
|
||||
groups ON groups.id = all_members.group_id
|
||||
WHERE
|
||||
users.deleted = 'false';
|
||||
|
||||
COMMENT ON VIEW group_members_expanded IS 'Joins group members with user information, organization ID, group name. Includes both regular group members and organization members (as part of the "Everyone" group).';
|
||||
@@ -0,0 +1,62 @@
|
||||
CREATE TABLE IF NOT EXISTS user_configs (
|
||||
user_id uuid NOT NULL,
|
||||
key varchar(256) NOT NULL,
|
||||
value text NOT NULL,
|
||||
|
||||
PRIMARY KEY (user_id, key),
|
||||
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
|
||||
-- Copy "theme_preference" from "users" table
|
||||
INSERT INTO user_configs (user_id, key, value)
|
||||
SELECT id, 'theme_preference', theme_preference
|
||||
FROM users
|
||||
WHERE users.theme_preference IS NOT NULL;
|
||||
|
||||
|
||||
-- Replace "group_members_expanded" without "theme_preference"
|
||||
DROP VIEW group_members_expanded;
|
||||
-- Taken from 000242_group_members_view.up.sql
|
||||
CREATE VIEW
|
||||
group_members_expanded
|
||||
AS
|
||||
-- If the group is a user made group, then we need to check the group_members table.
|
||||
-- If it is the "Everyone" group, then we need to check the organization_members table.
|
||||
WITH all_members AS (
|
||||
SELECT user_id, group_id FROM group_members
|
||||
UNION
|
||||
SELECT user_id, organization_id AS group_id FROM organization_members
|
||||
)
|
||||
SELECT
|
||||
users.id AS user_id,
|
||||
users.email AS user_email,
|
||||
users.username AS user_username,
|
||||
users.hashed_password AS user_hashed_password,
|
||||
users.created_at AS user_created_at,
|
||||
users.updated_at AS user_updated_at,
|
||||
users.status AS user_status,
|
||||
users.rbac_roles AS user_rbac_roles,
|
||||
users.login_type AS user_login_type,
|
||||
users.avatar_url AS user_avatar_url,
|
||||
users.deleted AS user_deleted,
|
||||
users.last_seen_at AS user_last_seen_at,
|
||||
users.quiet_hours_schedule AS user_quiet_hours_schedule,
|
||||
users.name AS user_name,
|
||||
users.github_com_user_id AS user_github_com_user_id,
|
||||
groups.organization_id AS organization_id,
|
||||
groups.name AS group_name,
|
||||
all_members.group_id AS group_id
|
||||
FROM
|
||||
all_members
|
||||
JOIN
|
||||
users ON users.id = all_members.user_id
|
||||
JOIN
|
||||
groups ON groups.id = all_members.group_id
|
||||
WHERE
|
||||
users.deleted = 'false';
|
||||
|
||||
COMMENT ON VIEW group_members_expanded IS 'Joins group members with user information, organization ID, group name. Includes both regular group members and organization members (as part of the "Everyone" group).';
|
||||
|
||||
-- Drop the "theme_preference" column now that the view no longer depends on it.
|
||||
ALTER TABLE users DROP COLUMN theme_preference;
|
||||
@@ -406,20 +406,19 @@ func ConvertUserRows(rows []GetUsersRow) []User {
|
||||
users := make([]User, len(rows))
|
||||
for i, r := range rows {
|
||||
users[i] = User{
|
||||
ID: r.ID,
|
||||
Email: r.Email,
|
||||
Username: r.Username,
|
||||
Name: r.Name,
|
||||
HashedPassword: r.HashedPassword,
|
||||
CreatedAt: r.CreatedAt,
|
||||
UpdatedAt: r.UpdatedAt,
|
||||
Status: r.Status,
|
||||
RBACRoles: r.RBACRoles,
|
||||
LoginType: r.LoginType,
|
||||
AvatarURL: r.AvatarURL,
|
||||
Deleted: r.Deleted,
|
||||
LastSeenAt: r.LastSeenAt,
|
||||
ThemePreference: r.ThemePreference,
|
||||
ID: r.ID,
|
||||
Email: r.Email,
|
||||
Username: r.Username,
|
||||
Name: r.Name,
|
||||
HashedPassword: r.HashedPassword,
|
||||
CreatedAt: r.CreatedAt,
|
||||
UpdatedAt: r.UpdatedAt,
|
||||
Status: r.Status,
|
||||
RBACRoles: r.RBACRoles,
|
||||
LoginType: r.LoginType,
|
||||
AvatarURL: r.AvatarURL,
|
||||
Deleted: r.Deleted,
|
||||
LastSeenAt: r.LastSeenAt,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -417,7 +417,6 @@ func (q *sqlQuerier) GetAuthorizedUsers(ctx context.Context, arg GetUsersParams,
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -505,7 +504,6 @@ func (q *sqlQuerier) GetAuthorizedAuditLogsOffset(ctx context.Context, arg GetAu
|
||||
&i.UserRoles,
|
||||
&i.UserAvatarUrl,
|
||||
&i.UserDeleted,
|
||||
&i.UserThemePreference,
|
||||
&i.UserQuietHoursSchedule,
|
||||
&i.OrganizationName,
|
||||
&i.OrganizationDisplayName,
|
||||
|
||||
@@ -2605,7 +2605,6 @@ type GroupMember struct {
|
||||
UserDeleted bool `db:"user_deleted" json:"user_deleted"`
|
||||
UserLastSeenAt time.Time `db:"user_last_seen_at" json:"user_last_seen_at"`
|
||||
UserQuietHoursSchedule string `db:"user_quiet_hours_schedule" json:"user_quiet_hours_schedule"`
|
||||
UserThemePreference string `db:"user_theme_preference" json:"user_theme_preference"`
|
||||
UserName string `db:"user_name" json:"user_name"`
|
||||
UserGithubComUserID sql.NullInt64 `db:"user_github_com_user_id" json:"user_github_com_user_id"`
|
||||
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
||||
@@ -3176,8 +3175,6 @@ type User struct {
|
||||
LastSeenAt time.Time `db:"last_seen_at" json:"last_seen_at"`
|
||||
// Daily (!) cron schedule (with optional CRON_TZ) signifying the start of the user's quiet hours. If empty, the default quiet hours on the instance is used instead.
|
||||
QuietHoursSchedule string `db:"quiet_hours_schedule" json:"quiet_hours_schedule"`
|
||||
// "" can be interpreted as "the user does not care", falling back to the default theme
|
||||
ThemePreference string `db:"theme_preference" json:"theme_preference"`
|
||||
// Name of the Coder user
|
||||
Name string `db:"name" json:"name"`
|
||||
// The GitHub.com numerical user ID. At time of implementation, this is used to check if the user has starred the Coder repository.
|
||||
@@ -3188,6 +3185,12 @@ type User struct {
|
||||
OneTimePasscodeExpiresAt sql.NullTime `db:"one_time_passcode_expires_at" json:"one_time_passcode_expires_at"`
|
||||
}
|
||||
|
||||
type UserConfig struct {
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
Key string `db:"key" json:"key"`
|
||||
Value string `db:"value" json:"value"`
|
||||
}
|
||||
|
||||
// Tracks when users were deleted
|
||||
type UserDeleted struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
|
||||
@@ -306,6 +306,7 @@ type sqlcQuerier interface {
|
||||
// produces a bloated value if a user has used multiple templates
|
||||
// simultaneously.
|
||||
GetUserActivityInsights(ctx context.Context, arg GetUserActivityInsightsParams) ([]GetUserActivityInsightsRow, error)
|
||||
GetUserAppearanceSettings(ctx context.Context, userID uuid.UUID) (string, error)
|
||||
GetUserByEmailOrUsername(ctx context.Context, arg GetUserByEmailOrUsernameParams) (User, error)
|
||||
GetUserByID(ctx context.Context, id uuid.UUID) (User, error)
|
||||
GetUserCount(ctx context.Context) (int64, error)
|
||||
@@ -522,7 +523,7 @@ type sqlcQuerier interface {
|
||||
UpdateTemplateVersionDescriptionByJobID(ctx context.Context, arg UpdateTemplateVersionDescriptionByJobIDParams) error
|
||||
UpdateTemplateVersionExternalAuthProvidersByJobID(ctx context.Context, arg UpdateTemplateVersionExternalAuthProvidersByJobIDParams) error
|
||||
UpdateTemplateWorkspacesLastUsedAt(ctx context.Context, arg UpdateTemplateWorkspacesLastUsedAtParams) error
|
||||
UpdateUserAppearanceSettings(ctx context.Context, arg UpdateUserAppearanceSettingsParams) (User, error)
|
||||
UpdateUserAppearanceSettings(ctx context.Context, arg UpdateUserAppearanceSettingsParams) (UserConfig, error)
|
||||
UpdateUserDeletedByID(ctx context.Context, id uuid.UUID) error
|
||||
UpdateUserGithubComUserID(ctx context.Context, arg UpdateUserGithubComUserIDParams) error
|
||||
UpdateUserHashedOneTimePasscode(ctx context.Context, arg UpdateUserHashedOneTimePasscodeParams) error
|
||||
|
||||
@@ -457,7 +457,6 @@ SELECT
|
||||
users.rbac_roles AS user_roles,
|
||||
users.avatar_url AS user_avatar_url,
|
||||
users.deleted AS user_deleted,
|
||||
users.theme_preference AS user_theme_preference,
|
||||
users.quiet_hours_schedule AS user_quiet_hours_schedule,
|
||||
COALESCE(organizations.name, '') AS organization_name,
|
||||
COALESCE(organizations.display_name, '') AS organization_display_name,
|
||||
@@ -608,7 +607,6 @@ type GetAuditLogsOffsetRow struct {
|
||||
UserRoles pq.StringArray `db:"user_roles" json:"user_roles"`
|
||||
UserAvatarUrl sql.NullString `db:"user_avatar_url" json:"user_avatar_url"`
|
||||
UserDeleted sql.NullBool `db:"user_deleted" json:"user_deleted"`
|
||||
UserThemePreference sql.NullString `db:"user_theme_preference" json:"user_theme_preference"`
|
||||
UserQuietHoursSchedule sql.NullString `db:"user_quiet_hours_schedule" json:"user_quiet_hours_schedule"`
|
||||
OrganizationName string `db:"organization_name" json:"organization_name"`
|
||||
OrganizationDisplayName string `db:"organization_display_name" json:"organization_display_name"`
|
||||
@@ -669,7 +667,6 @@ func (q *sqlQuerier) GetAuditLogsOffset(ctx context.Context, arg GetAuditLogsOff
|
||||
&i.UserRoles,
|
||||
&i.UserAvatarUrl,
|
||||
&i.UserDeleted,
|
||||
&i.UserThemePreference,
|
||||
&i.UserQuietHoursSchedule,
|
||||
&i.OrganizationName,
|
||||
&i.OrganizationDisplayName,
|
||||
@@ -1582,7 +1579,7 @@ func (q *sqlQuerier) DeleteGroupMemberFromGroup(ctx context.Context, arg DeleteG
|
||||
}
|
||||
|
||||
const getGroupMembers = `-- name: GetGroupMembers :many
|
||||
SELECT user_id, user_email, user_username, user_hashed_password, user_created_at, user_updated_at, user_status, user_rbac_roles, user_login_type, user_avatar_url, user_deleted, user_last_seen_at, user_quiet_hours_schedule, user_theme_preference, user_name, user_github_com_user_id, organization_id, group_name, group_id FROM group_members_expanded
|
||||
SELECT user_id, user_email, user_username, user_hashed_password, user_created_at, user_updated_at, user_status, user_rbac_roles, user_login_type, user_avatar_url, user_deleted, user_last_seen_at, user_quiet_hours_schedule, user_name, user_github_com_user_id, organization_id, group_name, group_id FROM group_members_expanded
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetGroupMembers(ctx context.Context) ([]GroupMember, error) {
|
||||
@@ -1608,7 +1605,6 @@ func (q *sqlQuerier) GetGroupMembers(ctx context.Context) ([]GroupMember, error)
|
||||
&i.UserDeleted,
|
||||
&i.UserLastSeenAt,
|
||||
&i.UserQuietHoursSchedule,
|
||||
&i.UserThemePreference,
|
||||
&i.UserName,
|
||||
&i.UserGithubComUserID,
|
||||
&i.OrganizationID,
|
||||
@@ -1629,7 +1625,7 @@ func (q *sqlQuerier) GetGroupMembers(ctx context.Context) ([]GroupMember, error)
|
||||
}
|
||||
|
||||
const getGroupMembersByGroupID = `-- name: GetGroupMembersByGroupID :many
|
||||
SELECT user_id, user_email, user_username, user_hashed_password, user_created_at, user_updated_at, user_status, user_rbac_roles, user_login_type, user_avatar_url, user_deleted, user_last_seen_at, user_quiet_hours_schedule, user_theme_preference, user_name, user_github_com_user_id, organization_id, group_name, group_id FROM group_members_expanded WHERE group_id = $1
|
||||
SELECT user_id, user_email, user_username, user_hashed_password, user_created_at, user_updated_at, user_status, user_rbac_roles, user_login_type, user_avatar_url, user_deleted, user_last_seen_at, user_quiet_hours_schedule, user_name, user_github_com_user_id, organization_id, group_name, group_id FROM group_members_expanded WHERE group_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetGroupMembersByGroupID(ctx context.Context, groupID uuid.UUID) ([]GroupMember, error) {
|
||||
@@ -1655,7 +1651,6 @@ func (q *sqlQuerier) GetGroupMembersByGroupID(ctx context.Context, groupID uuid.
|
||||
&i.UserDeleted,
|
||||
&i.UserLastSeenAt,
|
||||
&i.UserQuietHoursSchedule,
|
||||
&i.UserThemePreference,
|
||||
&i.UserName,
|
||||
&i.UserGithubComUserID,
|
||||
&i.OrganizationID,
|
||||
@@ -7777,7 +7772,7 @@ FROM
|
||||
(
|
||||
-- Select all groups this user is a member of. This will also include
|
||||
-- the "Everyone" group for organizations the user is a member of.
|
||||
SELECT user_id, user_email, user_username, user_hashed_password, user_created_at, user_updated_at, user_status, user_rbac_roles, user_login_type, user_avatar_url, user_deleted, user_last_seen_at, user_quiet_hours_schedule, user_theme_preference, user_name, user_github_com_user_id, organization_id, group_name, group_id FROM group_members_expanded
|
||||
SELECT user_id, user_email, user_username, user_hashed_password, user_created_at, user_updated_at, user_status, user_rbac_roles, user_login_type, user_avatar_url, user_deleted, user_last_seen_at, user_quiet_hours_schedule, user_name, user_github_com_user_id, organization_id, group_name, group_id FROM group_members_expanded
|
||||
WHERE
|
||||
$1 = user_id AND
|
||||
$2 = group_members_expanded.organization_id
|
||||
@@ -11359,9 +11354,26 @@ func (q *sqlQuerier) GetAuthorizationUserRoles(ctx context.Context, userID uuid.
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserAppearanceSettings = `-- name: GetUserAppearanceSettings :one
|
||||
SELECT
|
||||
value as theme_preference
|
||||
FROM
|
||||
user_configs
|
||||
WHERE
|
||||
user_id = $1
|
||||
AND key = 'theme_preference'
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetUserAppearanceSettings(ctx context.Context, userID uuid.UUID) (string, error) {
|
||||
row := q.db.QueryRowContext(ctx, getUserAppearanceSettings, userID)
|
||||
var theme_preference string
|
||||
err := row.Scan(&theme_preference)
|
||||
return theme_preference, 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, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
FROM
|
||||
users
|
||||
WHERE
|
||||
@@ -11393,7 +11405,6 @@ func (q *sqlQuerier) GetUserByEmailOrUsername(ctx context.Context, arg GetUserBy
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -11404,7 +11415,7 @@ func (q *sqlQuerier) GetUserByEmailOrUsername(ctx context.Context, arg GetUserBy
|
||||
|
||||
const getUserByID = `-- name: GetUserByID :one
|
||||
SELECT
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
FROM
|
||||
users
|
||||
WHERE
|
||||
@@ -11430,7 +11441,6 @@ func (q *sqlQuerier) GetUserByID(ctx context.Context, id uuid.UUID) (User, error
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -11457,7 +11467,7 @@ func (q *sqlQuerier) GetUserCount(ctx context.Context) (int64, error) {
|
||||
|
||||
const getUsers = `-- name: GetUsers :many
|
||||
SELECT
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, COUNT(*) OVER() AS count
|
||||
id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at, COUNT(*) OVER() AS count
|
||||
FROM
|
||||
users
|
||||
WHERE
|
||||
@@ -11567,7 +11577,6 @@ type GetUsersRow struct {
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
LastSeenAt time.Time `db:"last_seen_at" json:"last_seen_at"`
|
||||
QuietHoursSchedule string `db:"quiet_hours_schedule" json:"quiet_hours_schedule"`
|
||||
ThemePreference string `db:"theme_preference" json:"theme_preference"`
|
||||
Name string `db:"name" json:"name"`
|
||||
GithubComUserID sql.NullInt64 `db:"github_com_user_id" json:"github_com_user_id"`
|
||||
HashedOneTimePasscode []byte `db:"hashed_one_time_passcode" json:"hashed_one_time_passcode"`
|
||||
@@ -11610,7 +11619,6 @@ func (q *sqlQuerier) GetUsers(ctx context.Context, arg GetUsersParams) ([]GetUse
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -11631,7 +11639,7 @@ func (q *sqlQuerier) GetUsers(ctx context.Context, arg GetUsersParams) ([]GetUse
|
||||
}
|
||||
|
||||
const getUsersByIDs = `-- name: GetUsersByIDs :many
|
||||
SELECT id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at FROM users WHERE id = ANY($1 :: uuid [ ])
|
||||
SELECT id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at FROM users WHERE id = ANY($1 :: uuid [ ])
|
||||
`
|
||||
|
||||
// This shouldn't check for deleted, because it's frequently used
|
||||
@@ -11660,7 +11668,6 @@ func (q *sqlQuerier) GetUsersByIDs(ctx context.Context, ids []uuid.UUID) ([]User
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -11698,7 +11705,7 @@ VALUES
|
||||
-- if the status passed in is empty, fallback to dormant, which is what
|
||||
-- we were doing before.
|
||||
COALESCE(NULLIF($10::text, '')::user_status, 'dormant'::user_status)
|
||||
) RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
) RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
`
|
||||
|
||||
type InsertUserParams struct {
|
||||
@@ -11742,7 +11749,6 @@ func (q *sqlQuerier) InsertUser(ctx context.Context, arg InsertUserParams) (User
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -11804,45 +11810,29 @@ func (q *sqlQuerier) UpdateInactiveUsersToDormant(ctx context.Context, arg Updat
|
||||
}
|
||||
|
||||
const updateUserAppearanceSettings = `-- name: UpdateUserAppearanceSettings :one
|
||||
UPDATE
|
||||
users
|
||||
INSERT INTO
|
||||
user_configs (user_id, key, value)
|
||||
VALUES
|
||||
($1, 'theme_preference', $2)
|
||||
ON CONFLICT
|
||||
ON CONSTRAINT user_configs_pkey
|
||||
DO UPDATE
|
||||
SET
|
||||
theme_preference = $2,
|
||||
updated_at = $3
|
||||
WHERE
|
||||
id = $1
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
value = $2
|
||||
WHERE user_configs.user_id = $1
|
||||
AND user_configs.key = 'theme_preference'
|
||||
RETURNING user_id, key, value
|
||||
`
|
||||
|
||||
type UpdateUserAppearanceSettingsParams struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
ThemePreference string `db:"theme_preference" json:"theme_preference"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpdateUserAppearanceSettings(ctx context.Context, arg UpdateUserAppearanceSettingsParams) (User, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateUserAppearanceSettings, arg.ID, arg.ThemePreference, 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,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
&i.OneTimePasscodeExpiresAt,
|
||||
)
|
||||
func (q *sqlQuerier) UpdateUserAppearanceSettings(ctx context.Context, arg UpdateUserAppearanceSettingsParams) (UserConfig, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateUserAppearanceSettings, arg.UserID, arg.ThemePreference)
|
||||
var i UserConfig
|
||||
err := row.Scan(&i.UserID, &i.Key, &i.Value)
|
||||
return i, err
|
||||
}
|
||||
|
||||
@@ -11928,7 +11918,7 @@ SET
|
||||
last_seen_at = $2,
|
||||
updated_at = $3
|
||||
WHERE
|
||||
id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
`
|
||||
|
||||
type UpdateUserLastSeenAtParams struct {
|
||||
@@ -11954,7 +11944,6 @@ func (q *sqlQuerier) UpdateUserLastSeenAt(ctx context.Context, arg UpdateUserLas
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -11976,7 +11965,7 @@ SET
|
||||
'':: bytea
|
||||
END
|
||||
WHERE
|
||||
id = $2 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id = $2 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
`
|
||||
|
||||
type UpdateUserLoginTypeParams struct {
|
||||
@@ -12001,7 +11990,6 @@ func (q *sqlQuerier) UpdateUserLoginType(ctx context.Context, arg UpdateUserLogi
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -12021,7 +12009,7 @@ SET
|
||||
name = $6
|
||||
WHERE
|
||||
id = $1
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
`
|
||||
|
||||
type UpdateUserProfileParams struct {
|
||||
@@ -12057,7 +12045,6 @@ func (q *sqlQuerier) UpdateUserProfile(ctx context.Context, arg UpdateUserProfil
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -12073,7 +12060,7 @@ SET
|
||||
quiet_hours_schedule = $2
|
||||
WHERE
|
||||
id = $1
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
`
|
||||
|
||||
type UpdateUserQuietHoursScheduleParams struct {
|
||||
@@ -12098,7 +12085,6 @@ func (q *sqlQuerier) UpdateUserQuietHoursSchedule(ctx context.Context, arg Updat
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -12115,7 +12101,7 @@ SET
|
||||
rbac_roles = ARRAY(SELECT DISTINCT UNNEST($1 :: text[]))
|
||||
WHERE
|
||||
id = $2
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
`
|
||||
|
||||
type UpdateUserRolesParams struct {
|
||||
@@ -12140,7 +12126,6 @@ func (q *sqlQuerier) UpdateUserRoles(ctx context.Context, arg UpdateUserRolesPar
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
@@ -12156,7 +12141,7 @@ SET
|
||||
status = $2,
|
||||
updated_at = $3
|
||||
WHERE
|
||||
id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at
|
||||
`
|
||||
|
||||
type UpdateUserStatusParams struct {
|
||||
@@ -12182,7 +12167,6 @@ func (q *sqlQuerier) UpdateUserStatus(ctx context.Context, arg UpdateUserStatusP
|
||||
&i.Deleted,
|
||||
&i.LastSeenAt,
|
||||
&i.QuietHoursSchedule,
|
||||
&i.ThemePreference,
|
||||
&i.Name,
|
||||
&i.GithubComUserID,
|
||||
&i.HashedOneTimePasscode,
|
||||
|
||||
@@ -16,7 +16,6 @@ SELECT
|
||||
users.rbac_roles AS user_roles,
|
||||
users.avatar_url AS user_avatar_url,
|
||||
users.deleted AS user_deleted,
|
||||
users.theme_preference AS user_theme_preference,
|
||||
users.quiet_hours_schedule AS user_quiet_hours_schedule,
|
||||
COALESCE(organizations.name, '') AS organization_name,
|
||||
COALESCE(organizations.display_name, '') AS organization_display_name,
|
||||
|
||||
@@ -98,14 +98,27 @@ SET
|
||||
WHERE
|
||||
id = $1;
|
||||
|
||||
-- name: UpdateUserAppearanceSettings :one
|
||||
UPDATE
|
||||
users
|
||||
SET
|
||||
theme_preference = $2,
|
||||
updated_at = $3
|
||||
-- name: GetUserAppearanceSettings :one
|
||||
SELECT
|
||||
value as theme_preference
|
||||
FROM
|
||||
user_configs
|
||||
WHERE
|
||||
id = $1
|
||||
user_id = @user_id
|
||||
AND key = 'theme_preference';
|
||||
|
||||
-- name: UpdateUserAppearanceSettings :one
|
||||
INSERT INTO
|
||||
user_configs (user_id, key, value)
|
||||
VALUES
|
||||
(@user_id, 'theme_preference', @theme_preference)
|
||||
ON CONFLICT
|
||||
ON CONSTRAINT user_configs_pkey
|
||||
DO UPDATE
|
||||
SET
|
||||
value = @theme_preference
|
||||
WHERE user_configs.user_id = @user_id
|
||||
AND user_configs.key = 'theme_preference'
|
||||
RETURNING *;
|
||||
|
||||
-- name: UpdateUserRoles :one
|
||||
|
||||
@@ -65,6 +65,7 @@ const (
|
||||
UniqueTemplateVersionsPkey UniqueConstraint = "template_versions_pkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_pkey PRIMARY KEY (id);
|
||||
UniqueTemplateVersionsTemplateIDNameKey UniqueConstraint = "template_versions_template_id_name_key" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_template_id_name_key UNIQUE (template_id, name);
|
||||
UniqueTemplatesPkey UniqueConstraint = "templates_pkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_pkey PRIMARY KEY (id);
|
||||
UniqueUserConfigsPkey UniqueConstraint = "user_configs_pkey" // ALTER TABLE ONLY user_configs ADD CONSTRAINT user_configs_pkey PRIMARY KEY (user_id, key);
|
||||
UniqueUserDeletedPkey UniqueConstraint = "user_deleted_pkey" // ALTER TABLE ONLY user_deleted ADD CONSTRAINT user_deleted_pkey PRIMARY KEY (id);
|
||||
UniqueUserLinksPkey UniqueConstraint = "user_links_pkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_pkey PRIMARY KEY (user_id, login_type);
|
||||
UniqueUserStatusChangesPkey UniqueConstraint = "user_status_changes_pkey" // ALTER TABLE ONLY user_status_changes ADD CONSTRAINT user_status_changes_pkey PRIMARY KEY (id);
|
||||
|
||||
Reference in New Issue
Block a user