tenseleyflow/shithub / 1687110

Browse files

S11: migration 0017_repos.sql + reposdb sqlc package

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
16871101803fb1c10774211390d7d63d58d0d105
Parents
2aa27a0
Tree
aee94b6

9 changed files

StatusFile+-
M internal/meta/sqlc/models.go 65 0
A internal/migrationsfs/migrations/0017_repos.sql 70 0
A internal/repos/queries/repos.sql 46 0
A internal/repos/sqlc/db.go 25 0
C internal/repos/sqlc/models.go 0 0
A internal/repos/sqlc/querier.go 24 0
A internal/repos/sqlc/repos.sql.go 216 0
M internal/users/sqlc/models.go 65 0
M sqlc.yaml 16 0
internal/meta/sqlc/models.gomodified
@@ -5,11 +5,55 @@
5
 package metadb
5
 package metadb
6
 
6
 
7
 import (
7
 import (
8
+	"database/sql/driver"
9
+	"fmt"
8
 	"net/netip"
10
 	"net/netip"
9
 
11
 
10
 	"github.com/jackc/pgx/v5/pgtype"
12
 	"github.com/jackc/pgx/v5/pgtype"
11
 )
13
 )
12
 
14
 
15
+type RepoVisibility string
16
+
17
+const (
18
+	RepoVisibilityPublic  RepoVisibility = "public"
19
+	RepoVisibilityPrivate RepoVisibility = "private"
20
+)
21
+
22
+func (e *RepoVisibility) Scan(src interface{}) error {
23
+	switch s := src.(type) {
24
+	case []byte:
25
+		*e = RepoVisibility(s)
26
+	case string:
27
+		*e = RepoVisibility(s)
28
+	default:
29
+		return fmt.Errorf("unsupported scan type for RepoVisibility: %T", src)
30
+	}
31
+	return nil
32
+}
33
+
34
+type NullRepoVisibility struct {
35
+	RepoVisibility RepoVisibility
36
+	Valid          bool // Valid is true if RepoVisibility is not NULL
37
+}
38
+
39
+// Scan implements the Scanner interface.
40
+func (ns *NullRepoVisibility) Scan(value interface{}) error {
41
+	if value == nil {
42
+		ns.RepoVisibility, ns.Valid = "", false
43
+		return nil
44
+	}
45
+	ns.Valid = true
46
+	return ns.RepoVisibility.Scan(value)
47
+}
48
+
49
+// Value implements the driver Valuer interface.
50
+func (ns NullRepoVisibility) Value() (driver.Value, error) {
51
+	if !ns.Valid {
52
+		return nil, nil
53
+	}
54
+	return string(ns.RepoVisibility), nil
55
+}
56
+
13
 type AuthAuditLog struct {
57
 type AuthAuditLog struct {
14
 	ID         int64
58
 	ID         int64
15
 	ActorID    pgtype.Int8
59
 	ActorID    pgtype.Int8
@@ -52,6 +96,27 @@ type PasswordReset struct {
52
 	CreatedAt pgtype.Timestamptz
96
 	CreatedAt pgtype.Timestamptz
53
 }
97
 }
54
 
98
 
99
+type Repo struct {
100
+	ID              int64
101
+	OwnerUserID     pgtype.Int8
102
+	OwnerOrgID      pgtype.Int8
103
+	Name            string
104
+	Description     string
105
+	Visibility      RepoVisibility
106
+	DefaultBranch   string
107
+	IsArchived      bool
108
+	ArchivedAt      pgtype.Timestamptz
109
+	DeletedAt       pgtype.Timestamptz
110
+	DiskUsedBytes   int64
111
+	ForkOfRepoID    pgtype.Int8
112
+	LicenseKey      pgtype.Text
113
+	PrimaryLanguage pgtype.Text
114
+	HasIssues       bool
115
+	HasPulls        bool
116
+	CreatedAt       pgtype.Timestamptz
117
+	UpdatedAt       pgtype.Timestamptz
118
+}
119
+
55
 type User struct {
120
 type User struct {
56
 	ID                int64
121
 	ID                int64
57
 	Username          string
122
 	Username          string
internal/migrationsfs/migrations/0017_repos.sqladded
@@ -0,0 +1,70 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+--
3
+-- Repos table:
4
+--
5
+-- - One row per repository. Owner is XOR (user OR org); orgs land in
6
+--   S31 but the column exists from day 1 so the FK isn't a future
7
+--   destructive migration.
8
+-- - Name is citext so case-insensitive uniqueness comes for free.
9
+-- - default_branch is "trunk" by default; we'll let owners change it
10
+--   later. The bare repo on disk is created with the same default
11
+--   (--initial-branch=trunk via storage.RepoFS.InitBare).
12
+-- - Soft-delete + archive flags are introduced now so callers don't
13
+--   have to retrofit them later.
14
+-- - disk_used_bytes is the recorded post-init size; recalc job is S14.
15
+-- - has_issues / has_pulls let owners turn off these surfaces. Default
16
+--   on; the per-repo settings UI lands later.
17
+
18
+-- +goose Up
19
+CREATE TYPE repo_visibility AS ENUM ('public', 'private');
20
+
21
+CREATE TABLE repos (
22
+    id              bigserial   PRIMARY KEY,
23
+    owner_user_id   bigint      REFERENCES users(id) ON DELETE CASCADE,
24
+    owner_org_id    bigint, -- FK added when orgs ship in S31
25
+    name            citext      NOT NULL,
26
+    description     text        NOT NULL DEFAULT '',
27
+    visibility      repo_visibility NOT NULL DEFAULT 'public',
28
+    default_branch  text        NOT NULL DEFAULT 'trunk',
29
+    is_archived     boolean     NOT NULL DEFAULT false,
30
+    archived_at     timestamptz,
31
+    deleted_at      timestamptz,
32
+    disk_used_bytes bigint      NOT NULL DEFAULT 0,
33
+    fork_of_repo_id bigint      REFERENCES repos(id) ON DELETE SET NULL,
34
+    license_key     text,
35
+    primary_language text,
36
+    has_issues      boolean     NOT NULL DEFAULT true,
37
+    has_pulls       boolean     NOT NULL DEFAULT true,
38
+    created_at      timestamptz NOT NULL DEFAULT now(),
39
+    updated_at      timestamptz NOT NULL DEFAULT now(),
40
+
41
+    -- Exactly one owner kind. Until S31 ships orgs the right side is
42
+    -- always NULL; the constraint shape is forward-compatible.
43
+    CONSTRAINT repos_owner_xor CHECK (
44
+        (owner_user_id IS NOT NULL AND owner_org_id IS NULL)
45
+     OR (owner_user_id IS NULL     AND owner_org_id IS NOT NULL)
46
+    ),
47
+    CONSTRAINT repos_name_length CHECK (char_length(name::text) BETWEEN 1 AND 100),
48
+    CONSTRAINT repos_description_length CHECK (char_length(description) <= 350),
49
+    CONSTRAINT repos_default_branch_length CHECK (char_length(default_branch) BETWEEN 1 AND 100)
50
+);
51
+
52
+-- Per-owner uniqueness. Two partial indexes — one per owner kind —
53
+-- so a name can't collide within either bucket.
54
+CREATE UNIQUE INDEX repos_owner_user_name_idx
55
+    ON repos (owner_user_id, name)
56
+    WHERE owner_user_id IS NOT NULL;
57
+
58
+CREATE UNIQUE INDEX repos_owner_org_name_idx
59
+    ON repos (owner_org_id, name)
60
+    WHERE owner_org_id IS NOT NULL;
61
+
62
+CREATE INDEX repos_visibility_idx ON repos (visibility);
63
+CREATE INDEX repos_deleted_at_idx ON repos (deleted_at) WHERE deleted_at IS NOT NULL;
64
+
65
+CREATE TRIGGER set_updated_at BEFORE UPDATE ON repos
66
+    FOR EACH ROW EXECUTE FUNCTION tg_set_updated_at();
67
+
68
+-- +goose Down
69
+DROP TABLE IF EXISTS repos;
70
+DROP TYPE IF EXISTS repo_visibility;
internal/repos/queries/repos.sqladded
@@ -0,0 +1,46 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+
3
+-- name: CreateRepo :one
4
+INSERT INTO repos (
5
+    owner_user_id, owner_org_id, name, description, visibility,
6
+    default_branch, license_key, primary_language
7
+) VALUES (
8
+    $1, $2, $3, $4, $5, $6, $7, $8
9
+)
10
+RETURNING id, owner_user_id, owner_org_id, name, description, visibility,
11
+          default_branch, is_archived, archived_at, deleted_at,
12
+          disk_used_bytes, fork_of_repo_id, license_key, primary_language,
13
+          has_issues, has_pulls, created_at, updated_at;
14
+
15
+-- name: GetRepoByOwnerUserAndName :one
16
+SELECT id, owner_user_id, owner_org_id, name, description, visibility,
17
+       default_branch, is_archived, archived_at, deleted_at,
18
+       disk_used_bytes, fork_of_repo_id, license_key, primary_language,
19
+       has_issues, has_pulls, created_at, updated_at
20
+FROM repos
21
+WHERE owner_user_id = $1 AND name = $2 AND deleted_at IS NULL;
22
+
23
+-- name: ExistsRepoForOwnerUser :one
24
+SELECT EXISTS(
25
+    SELECT 1 FROM repos
26
+    WHERE owner_user_id = $1 AND name = $2 AND deleted_at IS NULL
27
+);
28
+
29
+-- name: ListReposForOwnerUser :many
30
+SELECT id, owner_user_id, owner_org_id, name, description, visibility,
31
+       default_branch, is_archived, archived_at, deleted_at,
32
+       disk_used_bytes, fork_of_repo_id, license_key, primary_language,
33
+       has_issues, has_pulls, created_at, updated_at
34
+FROM repos
35
+WHERE owner_user_id = $1 AND deleted_at IS NULL
36
+ORDER BY updated_at DESC;
37
+
38
+-- name: CountReposForOwnerUser :one
39
+SELECT count(*) FROM repos
40
+WHERE owner_user_id = $1 AND deleted_at IS NULL;
41
+
42
+-- name: SoftDeleteRepo :exec
43
+UPDATE repos SET deleted_at = now() WHERE id = $1;
44
+
45
+-- name: UpdateRepoDiskUsed :exec
46
+UPDATE repos SET disk_used_bytes = $2 WHERE id = $1;
internal/repos/sqlc/db.goadded
@@ -0,0 +1,25 @@
1
+// Code generated by sqlc. DO NOT EDIT.
2
+// versions:
3
+//   sqlc v1.31.1
4
+
5
+package reposdb
6
+
7
+import (
8
+	"context"
9
+
10
+	"github.com/jackc/pgx/v5"
11
+	"github.com/jackc/pgx/v5/pgconn"
12
+)
13
+
14
+type DBTX interface {
15
+	Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
16
+	Query(context.Context, string, ...interface{}) (pgx.Rows, error)
17
+	QueryRow(context.Context, string, ...interface{}) pgx.Row
18
+}
19
+
20
+func New() *Queries {
21
+	return &Queries{}
22
+}
23
+
24
+type Queries struct {
25
+}
internal/meta/sqlc/models.go → internal/repos/sqlc/models.gocopied (67% similarity)
@@ -2,14 +2,58 @@
2
 // versions:
2
 // versions:
3
 //   sqlc v1.31.1
3
 //   sqlc v1.31.1
4
 
4
 
5
-package metadb
5
+package reposdb
6
 
6
 
7
 import (
7
 import (
8
+	"database/sql/driver"
9
+	"fmt"
8
 	"net/netip"
10
 	"net/netip"
9
 
11
 
10
 	"github.com/jackc/pgx/v5/pgtype"
12
 	"github.com/jackc/pgx/v5/pgtype"
11
 )
13
 )
12
 
14
 
15
+type RepoVisibility string
16
+
17
+const (
18
+	RepoVisibilityPublic  RepoVisibility = "public"
19
+	RepoVisibilityPrivate RepoVisibility = "private"
20
+)
21
+
22
+func (e *RepoVisibility) Scan(src interface{}) error {
23
+	switch s := src.(type) {
24
+	case []byte:
25
+		*e = RepoVisibility(s)
26
+	case string:
27
+		*e = RepoVisibility(s)
28
+	default:
29
+		return fmt.Errorf("unsupported scan type for RepoVisibility: %T", src)
30
+	}
31
+	return nil
32
+}
33
+
34
+type NullRepoVisibility struct {
35
+	RepoVisibility RepoVisibility
36
+	Valid          bool // Valid is true if RepoVisibility is not NULL
37
+}
38
+
39
+// Scan implements the Scanner interface.
40
+func (ns *NullRepoVisibility) Scan(value interface{}) error {
41
+	if value == nil {
42
+		ns.RepoVisibility, ns.Valid = "", false
43
+		return nil
44
+	}
45
+	ns.Valid = true
46
+	return ns.RepoVisibility.Scan(value)
47
+}
48
+
49
+// Value implements the driver Valuer interface.
50
+func (ns NullRepoVisibility) Value() (driver.Value, error) {
51
+	if !ns.Valid {
52
+		return nil, nil
53
+	}
54
+	return string(ns.RepoVisibility), nil
55
+}
56
+
13
 type AuthAuditLog struct {
57
 type AuthAuditLog struct {
14
 	ID         int64
58
 	ID         int64
15
 	ActorID    pgtype.Int8
59
 	ActorID    pgtype.Int8
@@ -52,6 +96,27 @@ type PasswordReset struct {
52
 	CreatedAt pgtype.Timestamptz
96
 	CreatedAt pgtype.Timestamptz
53
 }
97
 }
54
 
98
 
99
+type Repo struct {
100
+	ID              int64
101
+	OwnerUserID     pgtype.Int8
102
+	OwnerOrgID      pgtype.Int8
103
+	Name            string
104
+	Description     string
105
+	Visibility      RepoVisibility
106
+	DefaultBranch   string
107
+	IsArchived      bool
108
+	ArchivedAt      pgtype.Timestamptz
109
+	DeletedAt       pgtype.Timestamptz
110
+	DiskUsedBytes   int64
111
+	ForkOfRepoID    pgtype.Int8
112
+	LicenseKey      pgtype.Text
113
+	PrimaryLanguage pgtype.Text
114
+	HasIssues       bool
115
+	HasPulls        bool
116
+	CreatedAt       pgtype.Timestamptz
117
+	UpdatedAt       pgtype.Timestamptz
118
+}
119
+
55
 type User struct {
120
 type User struct {
56
 	ID                int64
121
 	ID                int64
57
 	Username          string
122
 	Username          string
internal/repos/sqlc/querier.goadded
@@ -0,0 +1,24 @@
1
+// Code generated by sqlc. DO NOT EDIT.
2
+// versions:
3
+//   sqlc v1.31.1
4
+
5
+package reposdb
6
+
7
+import (
8
+	"context"
9
+
10
+	"github.com/jackc/pgx/v5/pgtype"
11
+)
12
+
13
+type Querier interface {
14
+	CountReposForOwnerUser(ctx context.Context, db DBTX, ownerUserID pgtype.Int8) (int64, error)
15
+	// SPDX-License-Identifier: AGPL-3.0-or-later
16
+	CreateRepo(ctx context.Context, db DBTX, arg CreateRepoParams) (Repo, error)
17
+	ExistsRepoForOwnerUser(ctx context.Context, db DBTX, arg ExistsRepoForOwnerUserParams) (bool, error)
18
+	GetRepoByOwnerUserAndName(ctx context.Context, db DBTX, arg GetRepoByOwnerUserAndNameParams) (Repo, error)
19
+	ListReposForOwnerUser(ctx context.Context, db DBTX, ownerUserID pgtype.Int8) ([]Repo, error)
20
+	SoftDeleteRepo(ctx context.Context, db DBTX, id int64) error
21
+	UpdateRepoDiskUsed(ctx context.Context, db DBTX, arg UpdateRepoDiskUsedParams) error
22
+}
23
+
24
+var _ Querier = (*Queries)(nil)
internal/repos/sqlc/repos.sql.goadded
@@ -0,0 +1,216 @@
1
+// Code generated by sqlc. DO NOT EDIT.
2
+// versions:
3
+//   sqlc v1.31.1
4
+// source: repos.sql
5
+
6
+package reposdb
7
+
8
+import (
9
+	"context"
10
+
11
+	"github.com/jackc/pgx/v5/pgtype"
12
+)
13
+
14
+const countReposForOwnerUser = `-- name: CountReposForOwnerUser :one
15
+SELECT count(*) FROM repos
16
+WHERE owner_user_id = $1 AND deleted_at IS NULL
17
+`
18
+
19
+func (q *Queries) CountReposForOwnerUser(ctx context.Context, db DBTX, ownerUserID pgtype.Int8) (int64, error) {
20
+	row := db.QueryRow(ctx, countReposForOwnerUser, ownerUserID)
21
+	var count int64
22
+	err := row.Scan(&count)
23
+	return count, err
24
+}
25
+
26
+const createRepo = `-- name: CreateRepo :one
27
+
28
+INSERT INTO repos (
29
+    owner_user_id, owner_org_id, name, description, visibility,
30
+    default_branch, license_key, primary_language
31
+) VALUES (
32
+    $1, $2, $3, $4, $5, $6, $7, $8
33
+)
34
+RETURNING id, owner_user_id, owner_org_id, name, description, visibility,
35
+          default_branch, is_archived, archived_at, deleted_at,
36
+          disk_used_bytes, fork_of_repo_id, license_key, primary_language,
37
+          has_issues, has_pulls, created_at, updated_at
38
+`
39
+
40
+type CreateRepoParams struct {
41
+	OwnerUserID     pgtype.Int8
42
+	OwnerOrgID      pgtype.Int8
43
+	Name            string
44
+	Description     string
45
+	Visibility      RepoVisibility
46
+	DefaultBranch   string
47
+	LicenseKey      pgtype.Text
48
+	PrimaryLanguage pgtype.Text
49
+}
50
+
51
+// SPDX-License-Identifier: AGPL-3.0-or-later
52
+func (q *Queries) CreateRepo(ctx context.Context, db DBTX, arg CreateRepoParams) (Repo, error) {
53
+	row := db.QueryRow(ctx, createRepo,
54
+		arg.OwnerUserID,
55
+		arg.OwnerOrgID,
56
+		arg.Name,
57
+		arg.Description,
58
+		arg.Visibility,
59
+		arg.DefaultBranch,
60
+		arg.LicenseKey,
61
+		arg.PrimaryLanguage,
62
+	)
63
+	var i Repo
64
+	err := row.Scan(
65
+		&i.ID,
66
+		&i.OwnerUserID,
67
+		&i.OwnerOrgID,
68
+		&i.Name,
69
+		&i.Description,
70
+		&i.Visibility,
71
+		&i.DefaultBranch,
72
+		&i.IsArchived,
73
+		&i.ArchivedAt,
74
+		&i.DeletedAt,
75
+		&i.DiskUsedBytes,
76
+		&i.ForkOfRepoID,
77
+		&i.LicenseKey,
78
+		&i.PrimaryLanguage,
79
+		&i.HasIssues,
80
+		&i.HasPulls,
81
+		&i.CreatedAt,
82
+		&i.UpdatedAt,
83
+	)
84
+	return i, err
85
+}
86
+
87
+const existsRepoForOwnerUser = `-- name: ExistsRepoForOwnerUser :one
88
+SELECT EXISTS(
89
+    SELECT 1 FROM repos
90
+    WHERE owner_user_id = $1 AND name = $2 AND deleted_at IS NULL
91
+)
92
+`
93
+
94
+type ExistsRepoForOwnerUserParams struct {
95
+	OwnerUserID pgtype.Int8
96
+	Name        string
97
+}
98
+
99
+func (q *Queries) ExistsRepoForOwnerUser(ctx context.Context, db DBTX, arg ExistsRepoForOwnerUserParams) (bool, error) {
100
+	row := db.QueryRow(ctx, existsRepoForOwnerUser, arg.OwnerUserID, arg.Name)
101
+	var exists bool
102
+	err := row.Scan(&exists)
103
+	return exists, err
104
+}
105
+
106
+const getRepoByOwnerUserAndName = `-- name: GetRepoByOwnerUserAndName :one
107
+SELECT id, owner_user_id, owner_org_id, name, description, visibility,
108
+       default_branch, is_archived, archived_at, deleted_at,
109
+       disk_used_bytes, fork_of_repo_id, license_key, primary_language,
110
+       has_issues, has_pulls, created_at, updated_at
111
+FROM repos
112
+WHERE owner_user_id = $1 AND name = $2 AND deleted_at IS NULL
113
+`
114
+
115
+type GetRepoByOwnerUserAndNameParams struct {
116
+	OwnerUserID pgtype.Int8
117
+	Name        string
118
+}
119
+
120
+func (q *Queries) GetRepoByOwnerUserAndName(ctx context.Context, db DBTX, arg GetRepoByOwnerUserAndNameParams) (Repo, error) {
121
+	row := db.QueryRow(ctx, getRepoByOwnerUserAndName, arg.OwnerUserID, arg.Name)
122
+	var i Repo
123
+	err := row.Scan(
124
+		&i.ID,
125
+		&i.OwnerUserID,
126
+		&i.OwnerOrgID,
127
+		&i.Name,
128
+		&i.Description,
129
+		&i.Visibility,
130
+		&i.DefaultBranch,
131
+		&i.IsArchived,
132
+		&i.ArchivedAt,
133
+		&i.DeletedAt,
134
+		&i.DiskUsedBytes,
135
+		&i.ForkOfRepoID,
136
+		&i.LicenseKey,
137
+		&i.PrimaryLanguage,
138
+		&i.HasIssues,
139
+		&i.HasPulls,
140
+		&i.CreatedAt,
141
+		&i.UpdatedAt,
142
+	)
143
+	return i, err
144
+}
145
+
146
+const listReposForOwnerUser = `-- name: ListReposForOwnerUser :many
147
+SELECT id, owner_user_id, owner_org_id, name, description, visibility,
148
+       default_branch, is_archived, archived_at, deleted_at,
149
+       disk_used_bytes, fork_of_repo_id, license_key, primary_language,
150
+       has_issues, has_pulls, created_at, updated_at
151
+FROM repos
152
+WHERE owner_user_id = $1 AND deleted_at IS NULL
153
+ORDER BY updated_at DESC
154
+`
155
+
156
+func (q *Queries) ListReposForOwnerUser(ctx context.Context, db DBTX, ownerUserID pgtype.Int8) ([]Repo, error) {
157
+	rows, err := db.Query(ctx, listReposForOwnerUser, ownerUserID)
158
+	if err != nil {
159
+		return nil, err
160
+	}
161
+	defer rows.Close()
162
+	items := []Repo{}
163
+	for rows.Next() {
164
+		var i Repo
165
+		if err := rows.Scan(
166
+			&i.ID,
167
+			&i.OwnerUserID,
168
+			&i.OwnerOrgID,
169
+			&i.Name,
170
+			&i.Description,
171
+			&i.Visibility,
172
+			&i.DefaultBranch,
173
+			&i.IsArchived,
174
+			&i.ArchivedAt,
175
+			&i.DeletedAt,
176
+			&i.DiskUsedBytes,
177
+			&i.ForkOfRepoID,
178
+			&i.LicenseKey,
179
+			&i.PrimaryLanguage,
180
+			&i.HasIssues,
181
+			&i.HasPulls,
182
+			&i.CreatedAt,
183
+			&i.UpdatedAt,
184
+		); err != nil {
185
+			return nil, err
186
+		}
187
+		items = append(items, i)
188
+	}
189
+	if err := rows.Err(); err != nil {
190
+		return nil, err
191
+	}
192
+	return items, nil
193
+}
194
+
195
+const softDeleteRepo = `-- name: SoftDeleteRepo :exec
196
+UPDATE repos SET deleted_at = now() WHERE id = $1
197
+`
198
+
199
+func (q *Queries) SoftDeleteRepo(ctx context.Context, db DBTX, id int64) error {
200
+	_, err := db.Exec(ctx, softDeleteRepo, id)
201
+	return err
202
+}
203
+
204
+const updateRepoDiskUsed = `-- name: UpdateRepoDiskUsed :exec
205
+UPDATE repos SET disk_used_bytes = $2 WHERE id = $1
206
+`
207
+
208
+type UpdateRepoDiskUsedParams struct {
209
+	ID            int64
210
+	DiskUsedBytes int64
211
+}
212
+
213
+func (q *Queries) UpdateRepoDiskUsed(ctx context.Context, db DBTX, arg UpdateRepoDiskUsedParams) error {
214
+	_, err := db.Exec(ctx, updateRepoDiskUsed, arg.ID, arg.DiskUsedBytes)
215
+	return err
216
+}
internal/users/sqlc/models.gomodified
@@ -5,11 +5,55 @@
5
 package usersdb
5
 package usersdb
6
 
6
 
7
 import (
7
 import (
8
+	"database/sql/driver"
9
+	"fmt"
8
 	"net/netip"
10
 	"net/netip"
9
 
11
 
10
 	"github.com/jackc/pgx/v5/pgtype"
12
 	"github.com/jackc/pgx/v5/pgtype"
11
 )
13
 )
12
 
14
 
15
+type RepoVisibility string
16
+
17
+const (
18
+	RepoVisibilityPublic  RepoVisibility = "public"
19
+	RepoVisibilityPrivate RepoVisibility = "private"
20
+)
21
+
22
+func (e *RepoVisibility) Scan(src interface{}) error {
23
+	switch s := src.(type) {
24
+	case []byte:
25
+		*e = RepoVisibility(s)
26
+	case string:
27
+		*e = RepoVisibility(s)
28
+	default:
29
+		return fmt.Errorf("unsupported scan type for RepoVisibility: %T", src)
30
+	}
31
+	return nil
32
+}
33
+
34
+type NullRepoVisibility struct {
35
+	RepoVisibility RepoVisibility
36
+	Valid          bool // Valid is true if RepoVisibility is not NULL
37
+}
38
+
39
+// Scan implements the Scanner interface.
40
+func (ns *NullRepoVisibility) Scan(value interface{}) error {
41
+	if value == nil {
42
+		ns.RepoVisibility, ns.Valid = "", false
43
+		return nil
44
+	}
45
+	ns.Valid = true
46
+	return ns.RepoVisibility.Scan(value)
47
+}
48
+
49
+// Value implements the driver Valuer interface.
50
+func (ns NullRepoVisibility) Value() (driver.Value, error) {
51
+	if !ns.Valid {
52
+		return nil, nil
53
+	}
54
+	return string(ns.RepoVisibility), nil
55
+}
56
+
13
 type AuthAuditLog struct {
57
 type AuthAuditLog struct {
14
 	ID         int64
58
 	ID         int64
15
 	ActorID    pgtype.Int8
59
 	ActorID    pgtype.Int8
@@ -52,6 +96,27 @@ type PasswordReset struct {
52
 	CreatedAt pgtype.Timestamptz
96
 	CreatedAt pgtype.Timestamptz
53
 }
97
 }
54
 
98
 
99
+type Repo struct {
100
+	ID              int64
101
+	OwnerUserID     pgtype.Int8
102
+	OwnerOrgID      pgtype.Int8
103
+	Name            string
104
+	Description     string
105
+	Visibility      RepoVisibility
106
+	DefaultBranch   string
107
+	IsArchived      bool
108
+	ArchivedAt      pgtype.Timestamptz
109
+	DeletedAt       pgtype.Timestamptz
110
+	DiskUsedBytes   int64
111
+	ForkOfRepoID    pgtype.Int8
112
+	LicenseKey      pgtype.Text
113
+	PrimaryLanguage pgtype.Text
114
+	HasIssues       bool
115
+	HasPulls        bool
116
+	CreatedAt       pgtype.Timestamptz
117
+	UpdatedAt       pgtype.Timestamptz
118
+}
119
+
55
 type User struct {
120
 type User struct {
56
 	ID                int64
121
 	ID                int64
57
 	Username          string
122
 	Username          string
sqlc.yamlmodified
@@ -33,3 +33,19 @@ sql:
33
         emit_exact_table_names: false
33
         emit_exact_table_names: false
34
         emit_empty_slices: true
34
         emit_empty_slices: true
35
         emit_methods_with_db_argument: true
35
         emit_methods_with_db_argument: true
36
+
37
+  - engine: postgresql
38
+    schema: internal/migrationsfs/migrations
39
+    queries: internal/repos/queries
40
+    gen:
41
+      go:
42
+        package: reposdb
43
+        out: internal/repos/sqlc
44
+        sql_package: pgx/v5
45
+        emit_json_tags: false
46
+        emit_pointers_for_null_types: false
47
+        emit_prepared_queries: false
48
+        emit_interface: true
49
+        emit_exact_table_names: false
50
+        emit_empty_slices: true
51
+        emit_methods_with_db_argument: true