diff --git a/store/datastore/builds_test.go b/store/datastore/builds_test.go index 19fed18a7..4aed2d326 100644 --- a/store/datastore/builds_test.go +++ b/store/datastore/builds_test.go @@ -32,7 +32,7 @@ func TestBuilds(t *testing.T) { // table data from the database. g.BeforeEach(func() { s.Exec("DELETE FROM builds") - s.Exec("DELETE FROM jobs") + s.Exec("DELETE FROM procs") }) g.It("Should Post a Build", func() { diff --git a/store/datastore/ddl/mysql/ddl_gen.go b/store/datastore/ddl/mysql/ddl_gen.go index 4350f78bd..ac12494a3 100644 --- a/store/datastore/ddl/mysql/ddl_gen.go +++ b/store/datastore/ddl/mysql/ddl_gen.go @@ -108,6 +108,34 @@ var migrations = []struct { name: "update-table-set-repo-seq-default", stmt: updateTableSetRepoSeqDefault, }, + { + name: "alter-table-add-repo-active", + stmt: alterTableAddRepoActive, + }, + { + name: "update-table-set-repo-active", + stmt: updateTableSetRepoActive, + }, + { + name: "alter-table-add-user-synced", + stmt: alterTableAddUserSynced, + }, + { + name: "update-table-set-user-synced", + stmt: updateTableSetUserSynced, + }, + { + name: "create-table-perms", + stmt: createTablePerms, + }, + { + name: "create-index-perms-repo", + stmt: createIndexPermsRepo, + }, + { + name: "create-index-perms-user", + stmt: createIndexPermsUser, + }, } // Migrate performs the database migration. If the migration fails @@ -499,3 +527,51 @@ var updateTableSetRepoSeqDefault = ` UPDATE repos SET repo_counter = 0 WHERE repo_counter IS NULL ` + +// +// 015_add_column_repo_active.sql +// + +var alterTableAddRepoActive = ` +ALTER TABLE repos ADD COLUMN repo_active BOOLEAN +` + +var updateTableSetRepoActive = ` +UPDATE repos SET repo_active = true +` + +// +// 016_add_column_user_synced.sql +// + +var alterTableAddUserSynced = ` +ALTER TABLE users ADD COLUMN user_synced INTEGER; +` + +var updateTableSetUserSynced = ` +UPDATE users SET user_synced = 0 +` + +// +// 017_create_table_perms.sql +// + +var createTablePerms = ` +CREATE TABLE IF NOT EXISTS perms ( + perm_user_id INTEGER NOT NULL +,perm_repo_id INTEGER NOT NULL +,perm_pull BOOLEAN +,perm_push BOOLEAN +,perm_admin BOOLEAN +,perm_synced INTEGER +,UNIQUE(perm_user_id, perm_repo_id) +); +` + +var createIndexPermsRepo = ` +CREATE INDEX ix_perms_repo ON perms (perm_repo_id); +` + +var createIndexPermsUser = ` +CREATE INDEX ix_perms_user ON perms (perm_user_id); +` diff --git a/store/datastore/ddl/mysql/files/015_add_column_repo_active.sql b/store/datastore/ddl/mysql/files/015_add_column_repo_active.sql new file mode 100644 index 000000000..4dca2dd1e --- /dev/null +++ b/store/datastore/ddl/mysql/files/015_add_column_repo_active.sql @@ -0,0 +1,7 @@ +-- name: alter-table-add-repo-active + +ALTER TABLE repos ADD COLUMN repo_active BOOLEAN + +-- name: update-table-set-repo-active + +UPDATE repos SET repo_active = true diff --git a/store/datastore/ddl/mysql/files/016_add_column_user_synced.sql b/store/datastore/ddl/mysql/files/016_add_column_user_synced.sql new file mode 100644 index 000000000..43db914e7 --- /dev/null +++ b/store/datastore/ddl/mysql/files/016_add_column_user_synced.sql @@ -0,0 +1,7 @@ +-- name: alter-table-add-user-synced + +ALTER TABLE users ADD COLUMN user_synced INTEGER; + +-- name: update-table-set-user-synced + +UPDATE users SET user_synced = 0 diff --git a/store/datastore/ddl/mysql/files/017_create_table_perms.sql b/store/datastore/ddl/mysql/files/017_create_table_perms.sql new file mode 100644 index 000000000..c40dc7f4b --- /dev/null +++ b/store/datastore/ddl/mysql/files/017_create_table_perms.sql @@ -0,0 +1,19 @@ +-- name: create-table-perms + +CREATE TABLE IF NOT EXISTS perms ( + perm_user_id INTEGER NOT NULL +,perm_repo_id INTEGER NOT NULL +,perm_pull BOOLEAN +,perm_push BOOLEAN +,perm_admin BOOLEAN +,perm_synced INTEGER +,UNIQUE(perm_user_id, perm_repo_id) +); + +-- name: create-index-perms-repo + +CREATE INDEX ix_perms_repo ON perms (perm_repo_id); + +-- name: create-index-perms-user + +CREATE INDEX ix_perms_user ON perms (perm_user_id); diff --git a/store/datastore/ddl/postgres/ddl_gen.go b/store/datastore/ddl/postgres/ddl_gen.go index 3212a7e15..d3416b31e 100644 --- a/store/datastore/ddl/postgres/ddl_gen.go +++ b/store/datastore/ddl/postgres/ddl_gen.go @@ -108,6 +108,34 @@ var migrations = []struct { name: "update-table-set-repo-seq-default", stmt: updateTableSetRepoSeqDefault, }, + { + name: "alter-table-add-repo-active", + stmt: alterTableAddRepoActive, + }, + { + name: "update-table-set-repo-active", + stmt: updateTableSetRepoActive, + }, + { + name: "alter-table-add-user-synced", + stmt: alterTableAddUserSynced, + }, + { + name: "update-table-set-user-synced", + stmt: updateTableSetUserSynced, + }, + { + name: "create-table-perms", + stmt: createTablePerms, + }, + { + name: "create-index-perms-repo", + stmt: createIndexPermsRepo, + }, + { + name: "create-index-perms-user", + stmt: createIndexPermsUser, + }, } // Migrate performs the database migration. If the migration fails @@ -499,3 +527,51 @@ var updateTableSetRepoSeqDefault = ` UPDATE repos SET repo_counter = 0 WHERE repo_counter IS NULL ` + +// +// 015_add_column_repo_active.sql +// + +var alterTableAddRepoActive = ` +ALTER TABLE repos ADD COLUMN repo_active BOOLEAN +` + +var updateTableSetRepoActive = ` +UPDATE repos SET repo_active = true +` + +// +// 016_add_column_user_synced.sql +// + +var alterTableAddUserSynced = ` +ALTER TABLE users ADD COLUMN user_synced INTEGER; +` + +var updateTableSetUserSynced = ` +UPDATE users SET user_synced = 0 +` + +// +// 017_create_table_perms.sql +// + +var createTablePerms = ` +CREATE TABLE IF NOT EXISTS perms ( + perm_user_id INTEGER NOT NULL +,perm_repo_id INTEGER NOT NULL +,perm_pull BOOLEAN +,perm_push BOOLEAN +,perm_admin BOOLEAN +,perm_synced INTEGER +,UNIQUE(perm_user_id, perm_repo_id) +); +` + +var createIndexPermsRepo = ` +CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id); +` + +var createIndexPermsUser = ` +CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id); +` diff --git a/store/datastore/ddl/postgres/files/015_add_column_repo_active.sql b/store/datastore/ddl/postgres/files/015_add_column_repo_active.sql new file mode 100644 index 000000000..4dca2dd1e --- /dev/null +++ b/store/datastore/ddl/postgres/files/015_add_column_repo_active.sql @@ -0,0 +1,7 @@ +-- name: alter-table-add-repo-active + +ALTER TABLE repos ADD COLUMN repo_active BOOLEAN + +-- name: update-table-set-repo-active + +UPDATE repos SET repo_active = true diff --git a/store/datastore/ddl/postgres/files/016_add_column_user_synced.sql b/store/datastore/ddl/postgres/files/016_add_column_user_synced.sql new file mode 100644 index 000000000..43db914e7 --- /dev/null +++ b/store/datastore/ddl/postgres/files/016_add_column_user_synced.sql @@ -0,0 +1,7 @@ +-- name: alter-table-add-user-synced + +ALTER TABLE users ADD COLUMN user_synced INTEGER; + +-- name: update-table-set-user-synced + +UPDATE users SET user_synced = 0 diff --git a/store/datastore/ddl/postgres/files/017_create_table_perms.sql b/store/datastore/ddl/postgres/files/017_create_table_perms.sql new file mode 100644 index 000000000..23da6223a --- /dev/null +++ b/store/datastore/ddl/postgres/files/017_create_table_perms.sql @@ -0,0 +1,19 @@ +-- name: create-table-perms + +CREATE TABLE IF NOT EXISTS perms ( + perm_user_id INTEGER NOT NULL +,perm_repo_id INTEGER NOT NULL +,perm_pull BOOLEAN +,perm_push BOOLEAN +,perm_admin BOOLEAN +,perm_synced INTEGER +,UNIQUE(perm_user_id, perm_repo_id) +); + +-- name: create-index-perms-repo + +CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id); + +-- name: create-index-perms-user + +CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id); diff --git a/store/datastore/perms_test.go b/store/datastore/perms_test.go index 9864151ee..113b550cb 100644 --- a/store/datastore/perms_test.go +++ b/store/datastore/perms_test.go @@ -136,3 +136,52 @@ func TestPermUpsert(t *testing.T) { t.Errorf("Wanted admin %v, got %v", want, got) } } + +func TestPermDelete(t *testing.T) { + s := newTest() + defer func() { + s.Exec("delete from perms") + s.Exec("delete from repos") + s.Close() + }() + + user := &model.User{ID: 1} + repo := &model.Repo{ + UserID: 1, + FullName: "bradrydzewski/drone", + Owner: "bradrydzewski", + Name: "drone", + } + s.CreateRepo(repo) + + err := s.PermUpsert( + &model.Perm{ + UserID: user.ID, + RepoID: repo.ID, + Repo: repo.FullName, + Pull: true, + Push: false, + Admin: false, + }, + ) + if err != nil { + t.Errorf("Unexpected error: insert perm: %s", err) + return + } + + perm, err := s.PermFind(user, repo) + if err != nil { + t.Errorf("Unexpected error: select perm: %s", err) + return + } + err = s.PermDelete(perm) + if err != nil { + t.Errorf("Unexpected error: delete perm: %s", err) + return + } + _, err = s.PermFind(user, repo) + if err == nil { + t.Errorf("Expect error: sql.ErrNoRows") + return + } +} diff --git a/store/datastore/repos.go b/store/datastore/repos.go index 372b1e265..eda92d901 100644 --- a/store/datastore/repos.go +++ b/store/datastore/repos.go @@ -1,8 +1,6 @@ package datastore import ( - "fmt" - "github.com/drone/drone/model" "github.com/drone/drone/store/datastore/sql" "github.com/russross/meddler" @@ -20,25 +18,6 @@ func (db *datastore) GetRepoName(name string) (*model.Repo, error) { return repo, err } -func (db *datastore) GetRepoListOf(listof []*model.RepoLite) ([]*model.Repo, error) { - var ( - repos []*model.Repo - args []interface{} - stmt string - err error - ) - switch meddler.Default { - case meddler.PostgreSQL: - stmt, args = toListPostgres(listof) - default: - stmt, args = toList(listof) - } - if len(args) > 0 { - err = meddler.QueryAll(db, &repos, fmt.Sprintf(repoListOfQuery, stmt), args...) - } - return repos, err -} - func (db *datastore) GetRepoCount() (count int, err error) { err = db.QueryRow( sql.Lookup(db.driver, "count-repos"), @@ -55,7 +34,8 @@ func (db *datastore) UpdateRepo(repo *model.Repo) error { } func (db *datastore) DeleteRepo(repo *model.Repo) error { - var _, err = db.Exec(rebind(repoDeleteStmt), repo.ID) + stmt := sql.Lookup(db.driver, "repo-delete") + _, err := db.Exec(stmt, repo.ID) return err } @@ -103,10 +83,6 @@ func (db *datastore) RepoBatch(repos []*model.Repo) error { if err != nil { return err } - // last, _ := res.LastInsertId() - // if last != 0 { - // repo.ID = last - // } } return nil } @@ -120,17 +96,6 @@ WHERE repo_full_name = ? LIMIT 1; ` -const repoListOfQuery = ` -SELECT * -FROM repos -WHERE repo_full_name IN (%s) -ORDER BY repo_name -` - -const repoCountQuery = ` -SELECT COUNT(*) FROM repos -` - const repoDeleteStmt = ` DELETE FROM repos WHERE repo_id = ? diff --git a/store/datastore/repos_test.go b/store/datastore/repos_test.go index 0d96aba47..3493a2147 100644 --- a/store/datastore/repos_test.go +++ b/store/datastore/repos_test.go @@ -84,76 +84,6 @@ func TestRepos(t *testing.T) { g.Assert(repo.Name).Equal(getrepo.Name) }) - g.It("Should Get a Repo List", func() { - repo1 := &model.Repo{ - UserID: 1, - Owner: "bradrydzewski", - Name: "drone", - FullName: "bradrydzewski/drone", - } - repo2 := &model.Repo{ - UserID: 2, - Owner: "drone", - Name: "drone", - FullName: "drone/drone", - } - repo3 := &model.Repo{ - UserID: 2, - Owner: "octocat", - Name: "hello-world", - FullName: "octocat/hello-world", - } - s.CreateRepo(repo1) - s.CreateRepo(repo2) - s.CreateRepo(repo3) - - repos, err := s.GetRepoListOf([]*model.RepoLite{ - {FullName: "bradrydzewski/drone"}, - {FullName: "drone/drone"}, - }) - g.Assert(err == nil).IsTrue() - g.Assert(len(repos)).Equal(2) - g.Assert(repos[0].ID).Equal(repo1.ID) - g.Assert(repos[1].ID).Equal(repo2.ID) - }) - - g.It("Should Get a Repo List", func() { - repo1 := &model.Repo{ - UserID: 1, - Owner: "bradrydzewski", - Name: "drone", - FullName: "bradrydzewski/drone", - } - repo2 := &model.Repo{ - UserID: 2, - Owner: "drone", - Name: "drone", - FullName: "drone/drone", - } - s.CreateRepo(repo1) - s.CreateRepo(repo2) - - count, err := s.GetRepoCount() - g.Assert(err == nil).IsTrue() - g.Assert(count).Equal(2) - }) - - g.It("Should Delete a Repo", func() { - repo := model.Repo{ - UserID: 1, - FullName: "bradrydzewski/drone", - Owner: "bradrydzewski", - Name: "drone", - } - s.CreateRepo(&repo) - _, err1 := s.GetRepo(repo.ID) - err2 := s.DeleteRepo(&repo) - _, err3 := s.GetRepo(repo.ID) - g.Assert(err1 == nil).IsTrue() - g.Assert(err2 == nil).IsTrue() - g.Assert(err3 == nil).IsFalse() - }) - g.It("Should Enforce Unique Repo Name", func() { repo1 := model.Repo{ UserID: 1, @@ -175,10 +105,187 @@ func TestRepos(t *testing.T) { }) } +func TestRepoList(t *testing.T) { + s := newTest() + s.Exec("delete from repos") + s.Exec("delete from users") + s.Exec("delete from perms") + + defer func() { + s.Exec("delete from repos") + s.Exec("delete from users") + s.Exec("delete from perms") + s.Close() + }() + + user := &model.User{ + Login: "joe", + Email: "foo@bar.com", + Token: "e42080dddf012c718e476da161d21ad5", + } + s.CreateUser(user) + + repo1 := &model.Repo{ + Owner: "bradrydzewski", + Name: "drone", + FullName: "bradrydzewski/drone", + } + repo2 := &model.Repo{ + Owner: "drone", + Name: "drone", + FullName: "drone/drone", + } + repo3 := &model.Repo{ + Owner: "octocat", + Name: "hello-world", + FullName: "octocat/hello-world", + } + s.CreateRepo(repo1) + s.CreateRepo(repo2) + s.CreateRepo(repo3) + + s.PermBatch([]*model.Perm{ + {UserID: user.ID, Repo: repo1.FullName}, + {UserID: user.ID, Repo: repo2.FullName}, + }) + + repos, err := s.RepoList(user) + if err != nil { + t.Error(err) + return + } + if got, want := len(repos), 2; got != want { + t.Errorf("Want %d repositories, got %d", want, got) + } + if got, want := repos[0].ID, repo1.ID; got != want { + t.Errorf("Want repository id %d, got %d", want, got) + } + if got, want := repos[1].ID, repo2.ID; got != want { + t.Errorf("Want repository id %d, got %d", want, got) + } +} + +func TestRepoListLatest(t *testing.T) { + s := newTest() + defer func() { + s.Exec("delete from repos") + s.Exec("delete from users") + s.Exec("delete from perms") + s.Close() + }() + + user := &model.User{ + Login: "joe", + Email: "foo@bar.com", + Token: "e42080dddf012c718e476da161d21ad5", + } + s.CreateUser(user) + + repo1 := &model.Repo{ + Owner: "bradrydzewski", + Name: "drone", + FullName: "bradrydzewski/drone", + IsActive: true, + } + repo2 := &model.Repo{ + Owner: "drone", + Name: "drone", + FullName: "drone/drone", + IsActive: true, + } + repo3 := &model.Repo{ + Owner: "octocat", + Name: "hello-world", + FullName: "octocat/hello-world", + IsActive: true, + } + s.CreateRepo(repo1) + s.CreateRepo(repo2) + s.CreateRepo(repo3) + + s.PermBatch([]*model.Perm{ + {UserID: user.ID, Repo: repo1.FullName}, + {UserID: user.ID, Repo: repo2.FullName}, + }) + + build1 := &model.Build{ + RepoID: repo1.ID, + Status: model.StatusFailure, + } + build2 := &model.Build{ + RepoID: repo1.ID, + Status: model.StatusRunning, + } + build3 := &model.Build{ + RepoID: repo2.ID, + Status: model.StatusKilled, + } + build4 := &model.Build{ + RepoID: repo3.ID, + Status: model.StatusError, + } + s.CreateBuild(build1) + s.CreateBuild(build2) + s.CreateBuild(build3) + s.CreateBuild(build4) + + builds, err := s.RepoListLatest(user) + if err != nil { + t.Errorf("Unexpected error: repository list with latest build: %s", err) + return + } + if got, want := len(builds), 2; got != want { + t.Errorf("Want %d repositories, got %d", want, got) + } + if got, want := builds[0].Status, model.StatusRunning; want != got { + t.Errorf("Want repository status %s, got %s", want, got) + } + if got, want := builds[0].FullName, repo1.FullName; want != got { + t.Errorf("Want repository name %s, got %s", want, got) + } + if got, want := builds[1].Status, model.StatusKilled; want != got { + t.Errorf("Want repository status %s, got %s", want, got) + } + if got, want := builds[1].FullName, repo2.FullName; want != got { + t.Errorf("Want repository name %s, got %s", want, got) + } +} + +func TestRepoCount(t *testing.T) { + s := newTest() + defer func() { + s.Exec("delete from repos") + s.Exec("delete from users") + s.Exec("delete from perms") + s.Close() + }() + + repo1 := &model.Repo{ + Owner: "bradrydzewski", + Name: "drone", + FullName: "bradrydzewski/drone", + } + repo2 := &model.Repo{ + Owner: "drone", + Name: "drone", + FullName: "drone/drone", + } + s.CreateRepo(repo1) + s.CreateRepo(repo2) + + s.Exec("ANALYZE") + count, _ := s.GetRepoCount() + if got, want := count, 2; got != want { + t.Errorf("Want %d repositories, got %d", want, got) + } +} + func TestRepoBatch(t *testing.T) { s := newTest() defer func() { s.Exec("delete from repos") + s.Exec("delete from users") + s.Exec("delete from perms") s.Close() }() @@ -221,8 +328,39 @@ func TestRepoBatch(t *testing.T) { return } + s.Exec("ANALYZE") count, _ := s.GetRepoCount() if got, want := count, 3; got != want { t.Errorf("Want %d repositories, got %d", want, got) } } + +func TestRepoCrud(t *testing.T) { + s := newTest() + defer func() { + s.Exec("delete from repos") + s.Exec("delete from users") + s.Exec("delete from perms") + s.Close() + }() + + repo := model.Repo{ + UserID: 1, + FullName: "bradrydzewski/drone", + Owner: "bradrydzewski", + Name: "drone", + } + s.CreateRepo(&repo) + _, err1 := s.GetRepo(repo.ID) + err2 := s.DeleteRepo(&repo) + _, err3 := s.GetRepo(repo.ID) + if err1 != nil { + t.Errorf("Unexpected error: select repository: %s", err1) + } + if err2 != nil { + t.Errorf("Unexpected error: delete repository: %s", err2) + } + if err3 == nil { + t.Errorf("Expected error: sql.ErrNoRows") + } +} diff --git a/store/datastore/secret_test.go b/store/datastore/secret_test.go index 16109b21b..c5b02883f 100644 --- a/store/datastore/secret_test.go +++ b/store/datastore/secret_test.go @@ -77,7 +77,7 @@ func TestSecretList(t *testing.T) { return } if got, want := len(list), 2; got != want { - t.Errorf("Want %d registries, got %d", want, got) + t.Errorf("Want %d secrets, got %d", want, got) } } @@ -112,6 +112,34 @@ func TestSecretUpdate(t *testing.T) { } } +func TestSecretDelete(t *testing.T) { + s := newTest() + defer func() { + s.Exec("delete from secrets") + s.Close() + }() + + secret := &model.Secret{ + RepoID: 1, + Name: "foo", + Value: "baz", + } + if err := s.SecretCreate(secret); err != nil { + t.Errorf("Unexpected error: insert secret: %s", err) + return + } + + if err := s.SecretDelete(secret); err != nil { + t.Errorf("Unexpected error: delete secret: %s", err) + return + } + _, err := s.SecretFind(&model.Repo{ID: 1}, "foo") + if err == nil { + t.Errorf("Expect error: sql.ErrNoRows") + return + } +} + func TestSecretIndexes(t *testing.T) { s := newTest() defer func() { diff --git a/store/datastore/sql/lookup.go b/store/datastore/sql/lookup.go index 6d9550af9..da3643f91 100644 --- a/store/datastore/sql/lookup.go +++ b/store/datastore/sql/lookup.go @@ -1,6 +1,7 @@ package sql import ( + "github.com/drone/drone/store/datastore/sql/mysql" "github.com/drone/drone/store/datastore/sql/postgres" "github.com/drone/drone/store/datastore/sql/sqlite" ) @@ -18,6 +19,8 @@ func Lookup(driver string, name string) string { switch driver { case DriverPostgres: return postgres.Lookup(name) + case DriverMysql: + return mysql.Lookup(name) default: return sqlite.Lookup(name) } diff --git a/store/datastore/sql/mysql/files/config.sql b/store/datastore/sql/mysql/files/config.sql new file mode 100644 index 000000000..8f29bd5d1 --- /dev/null +++ b/store/datastore/sql/mysql/files/config.sql @@ -0,0 +1,28 @@ +-- name: config-find-id + +SELECT + config_id +,config_repo_id +,config_hash +,config_data +FROM config +WHERE config_id = ? + +-- name: config-find-repo-hash + +SELECT + config_id +,config_repo_id +,config_hash +,config_data +FROM config +WHERE config_repo_id = ? + AND config_hash = ? + +-- name: config-find-approved + +SELECT build_id FROM builds +WHERE build_repo_id = ? +AND build_config_id = ? +AND build_status NOT IN ('blocked', 'pending') +LIMIT 1 diff --git a/store/datastore/sql/mysql/files/counts.sql b/store/datastore/sql/mysql/files/counts.sql new file mode 100644 index 000000000..23b73935b --- /dev/null +++ b/store/datastore/sql/mysql/files/counts.sql @@ -0,0 +1,14 @@ +-- name: count-users + +SELECT count(1) +FROM users + +-- name: count-repos + +SELECT count(1) +FROM repos + +-- name: count-builds + +SELECT count(1) +FROM builds diff --git a/store/datastore/sql/mysql/files/feed.sql b/store/datastore/sql/mysql/files/feed.sql new file mode 100644 index 000000000..8710a0a26 --- /dev/null +++ b/store/datastore/sql/mysql/files/feed.sql @@ -0,0 +1,61 @@ +-- name: feed-latest-build + +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos LEFT OUTER JOIN builds ON build_id = ( + SELECT build_id FROM builds + WHERE builds.build_repo_id = repos.repo_id + ORDER BY build_id DESC + LIMIT 1 +) +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +WHERE perms.perm_user_id = ? + AND repos.repo_active = true +ORDER BY repo_full_name ASC; + +-- name: feed + +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +INNER JOIN builds ON builds.build_repo_id = repos.repo_id +WHERE perms.perm_user_id = ? +ORDER BY build_id DESC +LIMIT 50 diff --git a/store/datastore/sql/mysql/files/files.sql b/store/datastore/sql/mysql/files/files.sql new file mode 100644 index 000000000..0088a218f --- /dev/null +++ b/store/datastore/sql/mysql/files/files.sql @@ -0,0 +1,45 @@ +-- name: files-find-build + +SELECT + file_id +,file_build_id +,file_proc_id +,file_name +,file_mime +,file_size +,file_time +FROM files +WHERE file_build_id = ? + +-- name: files-find-proc-name + +SELECT + file_id +,file_build_id +,file_proc_id +,file_name +,file_mime +,file_size +,file_time +FROM files +WHERE file_proc_id = ? + AND file_name = ? + +-- name: files-find-proc-name-data + +SELECT + file_id +,file_build_id +,file_proc_id +,file_name +,file_mime +,file_size +,file_time +,file_data +FROM files +WHERE file_proc_id = ? + AND file_name = ? + +-- name: files-delete-build + +DELETE FROM files WHERE file_build_id = ? diff --git a/store/datastore/sql/mysql/files/perms.sql b/store/datastore/sql/mysql/files/perms.sql new file mode 100644 index 000000000..15c80f969 --- /dev/null +++ b/store/datastore/sql/mysql/files/perms.sql @@ -0,0 +1,58 @@ +-- name: perms-find-user + +SELECT + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_date +FROM perms +WHERE perm_user_id = ? + +-- name: perms-find-user-repo + +SELECT + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +FROM perms +WHERE perm_user_id = ? + AND perm_repo_id = ? + +-- name: perms-insert-replace + +REPLACE INTO perms ( + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +) VALUES (?,?,?,?,?,?) + +-- name: perms-insert-replace-lookup + +REPLACE INTO perms ( + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?) + +-- name: perms-delete-user-repo + +DELETE FROM perms +WHERE perm_user_id = ? + AND perm_repo_id = ? + +-- name: perms-delete-user-date + +DELETE FROM perms +WHERE perm_user_id = ? + AND perm_synced < ? diff --git a/store/datastore/sql/mysql/files/procs.sql b/store/datastore/sql/mysql/files/procs.sql new file mode 100644 index 000000000..43ea11627 --- /dev/null +++ b/store/datastore/sql/mysql/files/procs.sql @@ -0,0 +1,87 @@ +-- name: procs-find-id + +SELECT + proc_id +,proc_build_id +,proc_pid +,proc_ppid +,proc_pgid +,proc_name +,proc_state +,proc_error +,proc_exit_code +,proc_started +,proc_stopped +,proc_machine +,proc_platform +,proc_environ +FROM procs +WHERE proc_id = ? + +-- name: procs-find-build + +SELECT + proc_id +,proc_build_id +,proc_pid +,proc_ppid +,proc_pgid +,proc_name +,proc_state +,proc_error +,proc_exit_code +,proc_started +,proc_stopped +,proc_machine +,proc_platform +,proc_environ +FROM procs +WHERE proc_build_id = ? +ORDER BY proc_id ASC + +-- name: procs-find-build-pid + +SELECT +proc_id +,proc_build_id +,proc_pid +,proc_ppid +,proc_pgid +,proc_name +,proc_state +,proc_error +,proc_exit_code +,proc_started +,proc_stopped +,proc_machine +,proc_platform +,proc_environ +FROM procs +WHERE proc_build_id = ? + AND proc_pid = ? + +-- name: procs-find-build-ppid + +SELECT +proc_id +,proc_build_id +,proc_pid +,proc_ppid +,proc_pgid +,proc_name +,proc_state +,proc_error +,proc_exit_code +,proc_started +,proc_stopped +,proc_machine +,proc_platform +,proc_environ +FROM procs +WHERE proc_build_id = ? + AND proc_ppid = ? + AND proc_name = ? + +-- name: procs-delete-build + +DELETE FROM procs WHERE proc_build_id = ? diff --git a/store/datastore/sql/mysql/files/registry.sql b/store/datastore/sql/mysql/files/registry.sql new file mode 100644 index 000000000..c28ae0f35 --- /dev/null +++ b/store/datastore/sql/mysql/files/registry.sql @@ -0,0 +1,34 @@ +-- name: registry-find-repo + +SELECT + registry_id +,registry_repo_id +,registry_addr +,registry_username +,registry_password +,registry_email +,registry_token +FROM registry +WHERE registry_repo_id = ? + +-- name: registry-find-repo-addr + +SELECT + registry_id +,registry_repo_id +,registry_addr +,registry_username +,registry_password +,registry_email +,registry_token +FROM registry +WHERE registry_repo_id = ? + AND registry_addr = ? + +-- name: registry-delete-repo + +DELETE FROM registry WHERE registry_repo_id = ? + +-- name: registry-delete + +DELETE FROM registry WHERE registry_id = ? diff --git a/store/datastore/sql/mysql/files/repos.sql b/store/datastore/sql/mysql/files/repos.sql new file mode 100644 index 000000000..5459fc6b5 --- /dev/null +++ b/store/datastore/sql/mysql/files/repos.sql @@ -0,0 +1,67 @@ +-- name: repo-update-counter + +UPDATE repos SET repo_counter = ? +WHERE repo_counter = ? + AND repo_id = ? + +-- name: repo-find-user + +SELECT + repo_id +,repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_avatar +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_private +,repo_trusted +,repo_active +,repo_allow_pr +,repo_allow_push +,repo_allow_deploys +,repo_allow_tags +,repo_hash +,repo_scm +,repo_config_path +,repo_gated +,repo_visibility +,repo_counter +FROM repos +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +WHERE perms.perm_user_id = ? +ORDER BY repo_full_name ASC + +-- name: repo-insert-ignore + +INSERT IGNORE INTO repos ( + repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_avatar +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_private +,repo_trusted +,repo_active +,repo_allow_pr +,repo_allow_push +,repo_allow_deploys +,repo_allow_tags +,repo_hash +,repo_scm +,repo_config_path +,repo_gated +,repo_visibility +,repo_counter +) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) + +-- name: repo-delete + +DELETE FROM repos WHERE repo_id = ? diff --git a/store/datastore/sql/mysql/files/secret.sql b/store/datastore/sql/mysql/files/secret.sql new file mode 100644 index 000000000..1eea03fa6 --- /dev/null +++ b/store/datastore/sql/mysql/files/secret.sql @@ -0,0 +1,32 @@ +-- name: secret-find-repo + +SELECT + secret_id +,secret_repo_id +,secret_name +,secret_value +,secret_images +,secret_events +,secret_conceal +,secret_skip_verify +FROM secrets +WHERE secret_repo_id = ? + +-- name: secret-find-repo-name + +SELECT +secret_id +,secret_repo_id +,secret_name +,secret_value +,secret_images +,secret_events +,secret_conceal +,secret_skip_verify +FROM secrets +WHERE secret_repo_id = ? + AND secret_name = ? + +-- name: secret-delete + +DELETE FROM secrets WHERE secret_id = ? diff --git a/store/datastore/sql/mysql/files/sender.sql b/store/datastore/sql/mysql/files/sender.sql new file mode 100644 index 000000000..7e87a6541 --- /dev/null +++ b/store/datastore/sql/mysql/files/sender.sql @@ -0,0 +1,30 @@ +-- name: sender-find-repo + +SELECT + sender_id +,sender_repo_id +,sender_login +,sender_allow +,sender_block +FROM senders +WHERE sender_repo_id = ? + +-- name: sender-find-repo-login + +SELECT + sender_id +,sender_repo_id +,sender_login +,sender_allow +,sender_block +FROM senders +WHERE sender_repo_id = ? + AND sender_login = ? + +-- name: sender-delete-repo + +DELETE FROM senders WHERE sender_repo_id = ? + +-- name: sender-delete + +DELETE FROM senders WHERE sender_id = ? diff --git a/store/datastore/sql/mysql/files/task.sql b/store/datastore/sql/mysql/files/task.sql new file mode 100644 index 000000000..5b61c7c5e --- /dev/null +++ b/store/datastore/sql/mysql/files/task.sql @@ -0,0 +1,11 @@ +-- name: task-list + +SELECT + task_id +,task_data +,task_labels +FROM tasks + +-- name: task-delete + +DELETE FROM tasks WHERE task_id = ? diff --git a/store/datastore/sql/mysql/sql.go b/store/datastore/sql/mysql/sql.go new file mode 100644 index 000000000..3e7d8abf6 --- /dev/null +++ b/store/datastore/sql/mysql/sql.go @@ -0,0 +1,3 @@ +package mysql + +//go:generate togo sql --package=mysql diff --git a/store/datastore/sql/mysql/sql_gen.go b/store/datastore/sql/mysql/sql_gen.go new file mode 100644 index 000000000..7225f31f8 --- /dev/null +++ b/store/datastore/sql/mysql/sql_gen.go @@ -0,0 +1,527 @@ +package mysql + +// Lookup returns the named statement. +func Lookup(name string) string { + return index[name] +} + +var index = map[string]string{ + "config-find-id": configFindId, + "config-find-repo-hash": configFindRepoHash, + "config-find-approved": configFindApproved, + "count-users": countUsers, + "count-repos": countRepos, + "count-builds": countBuilds, + "feed-latest-build": feedLatestBuild, + "feed": feed, + "files-find-build": filesFindBuild, + "files-find-proc-name": filesFindProcName, + "files-find-proc-name-data": filesFindProcNameData, + "files-delete-build": filesDeleteBuild, + "perms-find-user": permsFindUser, + "perms-find-user-repo": permsFindUserRepo, + "perms-insert-replace": permsInsertReplace, + "perms-insert-replace-lookup": permsInsertReplaceLookup, + "perms-delete-user-repo": permsDeleteUserRepo, + "perms-delete-user-date": permsDeleteUserDate, + "procs-find-id": procsFindId, + "procs-find-build": procsFindBuild, + "procs-find-build-pid": procsFindBuildPid, + "procs-find-build-ppid": procsFindBuildPpid, + "procs-delete-build": procsDeleteBuild, + "registry-find-repo": registryFindRepo, + "registry-find-repo-addr": registryFindRepoAddr, + "registry-delete-repo": registryDeleteRepo, + "registry-delete": registryDelete, + "repo-update-counter": repoUpdateCounter, + "repo-find-user": repoFindUser, + "repo-insert-ignore": repoInsertIgnore, + "repo-delete": repoDelete, + "secret-find-repo": secretFindRepo, + "secret-find-repo-name": secretFindRepoName, + "secret-delete": secretDelete, + "sender-find-repo": senderFindRepo, + "sender-find-repo-login": senderFindRepoLogin, + "sender-delete-repo": senderDeleteRepo, + "sender-delete": senderDelete, + "task-list": taskList, + "task-delete": taskDelete, +} + +var configFindId = ` +SELECT + config_id +,config_repo_id +,config_hash +,config_data +FROM config +WHERE config_id = ? +` + +var configFindRepoHash = ` +SELECT + config_id +,config_repo_id +,config_hash +,config_data +FROM config +WHERE config_repo_id = ? + AND config_hash = ? +` + +var configFindApproved = ` +SELECT build_id FROM builds +WHERE build_repo_id = ? +AND build_config_id = ? +AND build_status NOT IN ('blocked', 'pending') +LIMIT 1 +` + +var countUsers = ` +SELECT count(1) +FROM users +` + +var countRepos = ` +SELECT count(1) +FROM repos +` + +var countBuilds = ` +SELECT count(1) +FROM builds +` + +var feedLatestBuild = ` +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos LEFT OUTER JOIN builds ON build_id = ( + SELECT build_id FROM builds + WHERE builds.build_repo_id = repos.repo_id + ORDER BY build_id DESC + LIMIT 1 +) +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +WHERE perms.perm_user_id = ? + AND repos.repo_active = true +ORDER BY repo_full_name ASC; +` + +var feed = ` +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +INNER JOIN builds ON builds.build_repo_id = repos.repo_id +WHERE perms.perm_user_id = ? +ORDER BY build_id DESC +LIMIT 50 +` + +var filesFindBuild = ` +SELECT + file_id +,file_build_id +,file_proc_id +,file_name +,file_mime +,file_size +,file_time +FROM files +WHERE file_build_id = ? +` + +var filesFindProcName = ` +SELECT + file_id +,file_build_id +,file_proc_id +,file_name +,file_mime +,file_size +,file_time +FROM files +WHERE file_proc_id = ? + AND file_name = ? +` + +var filesFindProcNameData = ` +SELECT + file_id +,file_build_id +,file_proc_id +,file_name +,file_mime +,file_size +,file_time +,file_data +FROM files +WHERE file_proc_id = ? + AND file_name = ? +` + +var filesDeleteBuild = ` +DELETE FROM files WHERE file_build_id = ? +` + +var permsFindUser = ` +SELECT + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_date +FROM perms +WHERE perm_user_id = ? +` + +var permsFindUserRepo = ` +SELECT + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +FROM perms +WHERE perm_user_id = ? + AND perm_repo_id = ? +` + +var permsInsertReplace = ` +REPLACE INTO perms ( + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +) VALUES (?,?,?,?,?,?) +` + +var permsInsertReplaceLookup = ` +REPLACE INTO perms ( + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?) +` + +var permsDeleteUserRepo = ` +DELETE FROM perms +WHERE perm_user_id = ? + AND perm_repo_id = ? +` + +var permsDeleteUserDate = ` +DELETE FROM perms +WHERE perm_user_id = ? + AND perm_synced < ? +` + +var procsFindId = ` +SELECT + proc_id +,proc_build_id +,proc_pid +,proc_ppid +,proc_pgid +,proc_name +,proc_state +,proc_error +,proc_exit_code +,proc_started +,proc_stopped +,proc_machine +,proc_platform +,proc_environ +FROM procs +WHERE proc_id = ? +` + +var procsFindBuild = ` +SELECT + proc_id +,proc_build_id +,proc_pid +,proc_ppid +,proc_pgid +,proc_name +,proc_state +,proc_error +,proc_exit_code +,proc_started +,proc_stopped +,proc_machine +,proc_platform +,proc_environ +FROM procs +WHERE proc_build_id = ? +ORDER BY proc_id ASC +` + +var procsFindBuildPid = ` +SELECT +proc_id +,proc_build_id +,proc_pid +,proc_ppid +,proc_pgid +,proc_name +,proc_state +,proc_error +,proc_exit_code +,proc_started +,proc_stopped +,proc_machine +,proc_platform +,proc_environ +FROM procs +WHERE proc_build_id = ? + AND proc_pid = ? +` + +var procsFindBuildPpid = ` +SELECT +proc_id +,proc_build_id +,proc_pid +,proc_ppid +,proc_pgid +,proc_name +,proc_state +,proc_error +,proc_exit_code +,proc_started +,proc_stopped +,proc_machine +,proc_platform +,proc_environ +FROM procs +WHERE proc_build_id = ? + AND proc_ppid = ? + AND proc_name = ? +` + +var procsDeleteBuild = ` +DELETE FROM procs WHERE proc_build_id = ? +` + +var registryFindRepo = ` +SELECT + registry_id +,registry_repo_id +,registry_addr +,registry_username +,registry_password +,registry_email +,registry_token +FROM registry +WHERE registry_repo_id = ? +` + +var registryFindRepoAddr = ` +SELECT + registry_id +,registry_repo_id +,registry_addr +,registry_username +,registry_password +,registry_email +,registry_token +FROM registry +WHERE registry_repo_id = ? + AND registry_addr = ? +` + +var registryDeleteRepo = ` +DELETE FROM registry WHERE registry_repo_id = ? +` + +var registryDelete = ` +DELETE FROM registry WHERE registry_id = ? +` + +var repoUpdateCounter = ` +UPDATE repos SET repo_counter = ? +WHERE repo_counter = ? + AND repo_id = ? +` + +var repoFindUser = ` +SELECT + repo_id +,repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_avatar +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_private +,repo_trusted +,repo_active +,repo_allow_pr +,repo_allow_push +,repo_allow_deploys +,repo_allow_tags +,repo_hash +,repo_scm +,repo_config_path +,repo_gated +,repo_visibility +,repo_counter +FROM repos +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +WHERE perms.perm_user_id = ? +ORDER BY repo_full_name ASC +` + +var repoInsertIgnore = ` +INSERT IGNORE INTO repos ( + repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_avatar +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_private +,repo_trusted +,repo_active +,repo_allow_pr +,repo_allow_push +,repo_allow_deploys +,repo_allow_tags +,repo_hash +,repo_scm +,repo_config_path +,repo_gated +,repo_visibility +,repo_counter +) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) +` + +var repoDelete = ` +DELETE FROM repos WHERE repo_id = ? +` + +var secretFindRepo = ` +SELECT + secret_id +,secret_repo_id +,secret_name +,secret_value +,secret_images +,secret_events +,secret_conceal +,secret_skip_verify +FROM secrets +WHERE secret_repo_id = ? +` + +var secretFindRepoName = ` +SELECT +secret_id +,secret_repo_id +,secret_name +,secret_value +,secret_images +,secret_events +,secret_conceal +,secret_skip_verify +FROM secrets +WHERE secret_repo_id = ? + AND secret_name = ? +` + +var secretDelete = ` +DELETE FROM secrets WHERE secret_id = ? +` + +var senderFindRepo = ` +SELECT + sender_id +,sender_repo_id +,sender_login +,sender_allow +,sender_block +FROM senders +WHERE sender_repo_id = ? +` + +var senderFindRepoLogin = ` +SELECT + sender_id +,sender_repo_id +,sender_login +,sender_allow +,sender_block +FROM senders +WHERE sender_repo_id = ? + AND sender_login = ? +` + +var senderDeleteRepo = ` +DELETE FROM senders WHERE sender_repo_id = ? +` + +var senderDelete = ` +DELETE FROM senders WHERE sender_id = ? +` + +var taskList = ` +SELECT + task_id +,task_data +,task_labels +FROM tasks +` + +var taskDelete = ` +DELETE FROM tasks WHERE task_id = ? +` diff --git a/store/datastore/sql/postgres/files/feed.sql b/store/datastore/sql/postgres/files/feed.sql new file mode 100644 index 000000000..67cf802ca --- /dev/null +++ b/store/datastore/sql/postgres/files/feed.sql @@ -0,0 +1,61 @@ +-- name: feed-latest-build + +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos LEFT OUTER JOIN builds ON build_id = ( + SELECT build_id FROM builds + WHERE builds.build_repo_id = repos.repo_id + ORDER BY build_id DESC + LIMIT 1 +) +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +WHERE perms.perm_user_id = $1 + AND repos.repo_active = true +ORDER BY repo_full_name ASC; + +-- name: feed + +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +INNER JOIN builds ON builds.build_repo_id = repos.repo_id +WHERE perms.perm_user_id = $1 +ORDER BY build_id DESC +LIMIT 50 diff --git a/store/datastore/sql/postgres/files/perms.sql b/store/datastore/sql/postgres/files/perms.sql new file mode 100644 index 000000000..ea56e6417 --- /dev/null +++ b/store/datastore/sql/postgres/files/perms.sql @@ -0,0 +1,63 @@ +-- name: perms-find-user + +SELECT + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_date +FROM perms +WHERE perm_user_id = $1 + +-- name: perms-find-user-repo + +SELECT + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +FROM perms +WHERE perm_user_id = $1 + AND perm_repo_id = $2 + +-- name: perms-insert-replace + +REPLACE INTO perms ( + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +) VALUES ($1,$2,$3,$4,$5,$6) + +-- name: perms-insert-replace-lookup + +INSERT INTO perms ( + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +) VALUES ($1,(SELECT repo_id FROM repos WHERE repo_full_name = $2),$3,$4,$5,$6) +ON CONFLICT (perm_user_id, perm_repo_id) DO UPDATE SET + perm_pull = EXCLUDED.perm_pull +,perm_push = EXCLUDED.perm_push +,perm_admin = EXCLUDED.perm_admin +,perm_synced = EXCLUDED.perm_synced + +-- name: perms-delete-user-repo + +DELETE FROM perms +WHERE perm_user_id = $1 + AND perm_repo_id = $2 + +-- name: perms-delete-user-date + +DELETE FROM perms +WHERE perm_user_id = $1 + AND perm_synced < $2 diff --git a/store/datastore/sql/postgres/files/repos.sql b/store/datastore/sql/postgres/files/repos.sql index 7b07f5156..6c0eb1445 100644 --- a/store/datastore/sql/postgres/files/repos.sql +++ b/store/datastore/sql/postgres/files/repos.sql @@ -3,3 +3,67 @@ UPDATE repos SET repo_counter = $1 WHERE repo_counter = $2 AND repo_id = $3 + +-- name: repo-find-user + +SELECT + repo_id +,repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_avatar +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_private +,repo_trusted +,repo_active +,repo_allow_pr +,repo_allow_push +,repo_allow_deploys +,repo_allow_tags +,repo_hash +,repo_scm +,repo_config_path +,repo_gated +,repo_visibility +,repo_counter +FROM repos +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +WHERE perms.perm_user_id = $1 +ORDER BY repo_full_name ASC + +-- name: repo-insert-ignore + +INSERT INTO repos ( + repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_avatar +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_private +,repo_trusted +,repo_active +,repo_allow_pr +,repo_allow_push +,repo_allow_deploys +,repo_allow_tags +,repo_hash +,repo_scm +,repo_config_path +,repo_gated +,repo_visibility +,repo_counter +) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22) +ON CONFLICT (repo_full_name) DO NOTHING + +-- name: repo-delete + +DELETE FROM repos +WHERE repo_id = $1 diff --git a/store/datastore/sql/postgres/sql_gen.go b/store/datastore/sql/postgres/sql_gen.go index 3eee16d34..44356a447 100644 --- a/store/datastore/sql/postgres/sql_gen.go +++ b/store/datastore/sql/postgres/sql_gen.go @@ -6,35 +6,46 @@ func Lookup(name string) string { } var index = map[string]string{ - "config-find-id": configFindId, - "config-find-repo-hash": configFindRepoHash, - "config-find-approved": configFindApproved, - "count-users": countUsers, - "count-repos": countRepos, - "count-builds": countBuilds, - "files-find-build": filesFindBuild, - "files-find-proc-name": filesFindProcName, - "files-find-proc-name-data": filesFindProcNameData, - "files-delete-build": filesDeleteBuild, - "procs-find-id": procsFindId, - "procs-find-build": procsFindBuild, - "procs-find-build-pid": procsFindBuildPid, - "procs-find-build-ppid": procsFindBuildPpid, - "procs-delete-build": procsDeleteBuild, - "registry-find-repo": registryFindRepo, - "registry-find-repo-addr": registryFindRepoAddr, - "registry-delete-repo": registryDeleteRepo, - "registry-delete": registryDelete, - "repo-update-counter": repoUpdateCounter, - "secret-find-repo": secretFindRepo, - "secret-find-repo-name": secretFindRepoName, - "secret-delete": secretDelete, - "sender-find-repo": senderFindRepo, - "sender-find-repo-login": senderFindRepoLogin, - "sender-delete-repo": senderDeleteRepo, - "sender-delete": senderDelete, - "task-list": taskList, - "task-delete": taskDelete, + "config-find-id": configFindId, + "config-find-repo-hash": configFindRepoHash, + "config-find-approved": configFindApproved, + "count-users": countUsers, + "count-repos": countRepos, + "count-builds": countBuilds, + "feed-latest-build": feedLatestBuild, + "feed": feed, + "files-find-build": filesFindBuild, + "files-find-proc-name": filesFindProcName, + "files-find-proc-name-data": filesFindProcNameData, + "files-delete-build": filesDeleteBuild, + "perms-find-user": permsFindUser, + "perms-find-user-repo": permsFindUserRepo, + "perms-insert-replace": permsInsertReplace, + "perms-insert-replace-lookup": permsInsertReplaceLookup, + "perms-delete-user-repo": permsDeleteUserRepo, + "perms-delete-user-date": permsDeleteUserDate, + "procs-find-id": procsFindId, + "procs-find-build": procsFindBuild, + "procs-find-build-pid": procsFindBuildPid, + "procs-find-build-ppid": procsFindBuildPpid, + "procs-delete-build": procsDeleteBuild, + "registry-find-repo": registryFindRepo, + "registry-find-repo-addr": registryFindRepoAddr, + "registry-delete-repo": registryDeleteRepo, + "registry-delete": registryDelete, + "repo-update-counter": repoUpdateCounter, + "repo-find-user": repoFindUser, + "repo-insert-ignore": repoInsertIgnore, + "repo-delete": repoDelete, + "secret-find-repo": secretFindRepo, + "secret-find-repo-name": secretFindRepoName, + "secret-delete": secretDelete, + "sender-find-repo": senderFindRepo, + "sender-find-repo-login": senderFindRepoLogin, + "sender-delete-repo": senderDeleteRepo, + "sender-delete": senderDelete, + "task-list": taskList, + "task-delete": taskDelete, } var configFindId = ` @@ -81,6 +92,68 @@ SELECT reltuples FROM pg_class WHERE relname = 'builds'; ` +var feedLatestBuild = ` +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos LEFT OUTER JOIN builds ON build_id = ( + SELECT build_id FROM builds + WHERE builds.build_repo_id = repos.repo_id + ORDER BY build_id DESC + LIMIT 1 +) +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +WHERE perms.perm_user_id = $1 + AND repos.repo_active = true +ORDER BY repo_full_name ASC; +` + +var feed = ` +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +INNER JOIN builds ON builds.build_repo_id = repos.repo_id +WHERE perms.perm_user_id = $1 +ORDER BY build_id DESC +LIMIT 50 +` + var filesFindBuild = ` SELECT file_id @@ -127,6 +200,70 @@ var filesDeleteBuild = ` DELETE FROM files WHERE file_build_id = $1 ` +var permsFindUser = ` +SELECT + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_date +FROM perms +WHERE perm_user_id = $1 +` + +var permsFindUserRepo = ` +SELECT + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +FROM perms +WHERE perm_user_id = $1 + AND perm_repo_id = $2 +` + +var permsInsertReplace = ` +REPLACE INTO perms ( + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +) VALUES ($1,$2,$3,$4,$5,$6) +` + +var permsInsertReplaceLookup = ` +INSERT INTO perms ( + perm_user_id +,perm_repo_id +,perm_pull +,perm_push +,perm_admin +,perm_synced +) VALUES ($1,(SELECT repo_id FROM repos WHERE repo_full_name = $2),$3,$4,$5,$6) +ON CONFLICT (perm_user_id, perm_repo_id) DO UPDATE SET + perm_pull = EXCLUDED.perm_pull +,perm_push = EXCLUDED.perm_push +,perm_admin = EXCLUDED.perm_admin +,perm_synced = EXCLUDED.perm_synced +` + +var permsDeleteUserRepo = ` +DELETE FROM perms +WHERE perm_user_id = $1 + AND perm_repo_id = $2 +` + +var permsDeleteUserDate = ` +DELETE FROM perms +WHERE perm_user_id = $1 + AND perm_synced < $2 +` + var procsFindId = ` SELECT proc_id @@ -256,6 +393,70 @@ WHERE repo_counter = $2 AND repo_id = $3 ` +var repoFindUser = ` +SELECT + repo_id +,repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_avatar +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_private +,repo_trusted +,repo_active +,repo_allow_pr +,repo_allow_push +,repo_allow_deploys +,repo_allow_tags +,repo_hash +,repo_scm +,repo_config_path +,repo_gated +,repo_visibility +,repo_counter +FROM repos +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +WHERE perms.perm_user_id = $1 +ORDER BY repo_full_name ASC +` + +var repoInsertIgnore = ` +INSERT INTO repos ( + repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_avatar +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_private +,repo_trusted +,repo_active +,repo_allow_pr +,repo_allow_push +,repo_allow_deploys +,repo_allow_tags +,repo_hash +,repo_scm +,repo_config_path +,repo_gated +,repo_visibility +,repo_counter +) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22) +ON CONFLICT (repo_full_name) DO NOTHING +` + +var repoDelete = ` +DELETE FROM repos +WHERE repo_id = $1 +` + var secretFindRepo = ` SELECT secret_id diff --git a/store/datastore/sql/sqlite/files/perms.sql b/store/datastore/sql/sqlite/files/perms.sql index c0d85356c..15c80f969 100644 --- a/store/datastore/sql/sqlite/files/perms.sql +++ b/store/datastore/sql/sqlite/files/perms.sql @@ -25,7 +25,7 @@ WHERE perm_user_id = ? -- name: perms-insert-replace -INSERT OR REPLACE INTO perms ( +REPLACE INTO perms ( perm_user_id ,perm_repo_id ,perm_pull @@ -36,7 +36,7 @@ INSERT OR REPLACE INTO perms ( -- name: perms-insert-replace-lookup -INSERT OR REPLACE INTO perms ( +REPLACE INTO perms ( perm_user_id ,perm_repo_id ,perm_pull diff --git a/store/datastore/sql/sqlite/files/repos.sql b/store/datastore/sql/sqlite/files/repos.sql index 94dfdcea3..2aba7acf6 100644 --- a/store/datastore/sql/sqlite/files/repos.sql +++ b/store/datastore/sql/sqlite/files/repos.sql @@ -61,3 +61,7 @@ INSERT OR IGNORE INTO repos ( ,repo_visibility ,repo_counter ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) + +-- name: repo-delete + +DELETE FROM repos WHERE repo_id = ? diff --git a/store/datastore/sql/sqlite/sql_gen.go b/store/datastore/sql/sqlite/sql_gen.go index 38ce3d411..1728b2cc3 100644 --- a/store/datastore/sql/sqlite/sql_gen.go +++ b/store/datastore/sql/sqlite/sql_gen.go @@ -36,6 +36,7 @@ var index = map[string]string{ "repo-update-counter": repoUpdateCounter, "repo-find-user": repoFindUser, "repo-insert-ignore": repoInsertIgnore, + "repo-delete": repoDelete, "secret-find-repo": secretFindRepo, "secret-find-repo-name": secretFindRepoName, "secret-delete": secretDelete, @@ -225,7 +226,7 @@ WHERE perm_user_id = ? ` var permsInsertReplace = ` -INSERT OR REPLACE INTO perms ( +REPLACE INTO perms ( perm_user_id ,perm_repo_id ,perm_pull @@ -236,7 +237,7 @@ INSERT OR REPLACE INTO perms ( ` var permsInsertReplaceLookup = ` -INSERT OR REPLACE INTO perms ( +REPLACE INTO perms ( perm_user_id ,perm_repo_id ,perm_pull @@ -445,6 +446,10 @@ INSERT OR IGNORE INTO repos ( ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ` +var repoDelete = ` +DELETE FROM repos WHERE repo_id = ? +` + var secretFindRepo = ` SELECT secret_id diff --git a/store/datastore/users.go b/store/datastore/users.go index 8aa91894c..41df6ca44 100644 --- a/store/datastore/users.go +++ b/store/datastore/users.go @@ -1,8 +1,6 @@ package datastore import ( - "fmt" - "github.com/drone/drone/model" "github.com/drone/drone/store/datastore/sql" "github.com/russross/meddler" @@ -26,46 +24,6 @@ func (db *datastore) GetUserList() ([]*model.User, error) { return users, err } -func (db *datastore) GetUserFeed(listof []*model.RepoLite) ([]*model.Feed, error) { - var ( - args []interface{} - stmt string - err error - - feed = []*model.Feed{} - ) - switch meddler.Default { - case meddler.PostgreSQL: - stmt, args = toListPostgres(listof) - default: - stmt, args = toList(listof) - } - if len(args) > 0 { - err = meddler.QueryAll(db, &feed, fmt.Sprintf(userFeedQuery, stmt), args...) - } - return feed, err -} - -func (db *datastore) GetUserFeedLatest(listof []*model.RepoLite) ([]*model.Feed, error) { - var ( - args []interface{} - stmt string - err error - - feed = []*model.Feed{} - ) - switch meddler.Default { - case meddler.PostgreSQL: - stmt, args = toListPostgres(listof) - default: - stmt, args = toList(listof) - } - if len(args) > 0 { - err = meddler.QueryAll(db, &feed, fmt.Sprintf(userFeedLatest, stmt), args...) - } - return feed, err -} - func (db *datastore) GetUserCount() (count int, err error) { err = db.QueryRow( sql.Lookup(db.driver, "count-users"), @@ -108,75 +66,7 @@ FROM users ORDER BY user_login ASC ` -const userCountQuery = ` -SELECT count(1) -FROM users -` - const userDeleteStmt = ` DELETE FROM users WHERE user_id=? ` - -const userFeedQuery = ` -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM - builds b -,repos r -WHERE b.build_repo_id = r.repo_id - AND r.repo_full_name IN (%s) -ORDER BY b.build_id DESC -LIMIT 50 -` - -// thanks to this article for helping me find a sane sql query -// https://www.periscopedata.com/blog/4-ways-to-join-only-the-first-row-in-sql.html - -const userFeedLatest = ` -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos LEFT OUTER JOIN builds ON build_id = ( - SELECT build_id FROM builds - WHERE builds.build_repo_id = repos.repo_id - ORDER BY build_id DESC - LIMIT 1 -) -WHERE repo_full_name IN (%s) -` diff --git a/store/datastore/users_test.go b/store/datastore/users_test.go index 37d45a7e5..f37dbce56 100644 --- a/store/datastore/users_test.go +++ b/store/datastore/users_test.go @@ -20,7 +20,7 @@ func TestUsers(t *testing.T) { s.Exec("DELETE FROM users") s.Exec("DELETE FROM repos") s.Exec("DELETE FROM builds") - s.Exec("DELETE FROM jobs") + s.Exec("DELETE FROM procs") }) g.It("Should Update a User", func() { @@ -166,28 +166,40 @@ func TestUsers(t *testing.T) { }) g.It("Should get the Build feed for a User", func() { + user := &model.User{ + Login: "joe", + Email: "foo@bar.com", + Token: "e42080dddf012c718e476da161d21ad5", + } + s.CreateUser(user) + repo1 := &model.Repo{ - UserID: 1, Owner: "bradrydzewski", Name: "drone", FullName: "bradrydzewski/drone", + IsActive: true, } repo2 := &model.Repo{ - UserID: 2, Owner: "drone", Name: "drone", FullName: "drone/drone", + IsActive: true, } repo3 := &model.Repo{ - UserID: 2, Owner: "octocat", Name: "hello-world", FullName: "octocat/hello-world", + IsActive: true, } s.CreateRepo(repo1) s.CreateRepo(repo2) s.CreateRepo(repo3) + s.PermBatch([]*model.Perm{ + {UserID: user.ID, Repo: repo1.FullName}, + {UserID: user.ID, Repo: repo2.FullName}, + }) + build1 := &model.Build{ RepoID: repo1.ID, Status: model.StatusFailure, @@ -209,10 +221,7 @@ func TestUsers(t *testing.T) { s.CreateBuild(build3) s.CreateBuild(build4) - builds, err := s.GetUserFeed([]*model.RepoLite{ - {FullName: "bradrydzewski/drone"}, - {FullName: "drone/drone"}, - }) + builds, err := s.UserFeed(user) g.Assert(err == nil).IsTrue() g.Assert(len(builds)).Equal(3) g.Assert(builds[0].FullName).Equal(repo2.FullName) diff --git a/store/datastore/utils.go b/store/datastore/utils.go index e2345dd32..dbf0e8b75 100644 --- a/store/datastore/utils.go +++ b/store/datastore/utils.go @@ -2,9 +2,7 @@ package datastore import ( "strconv" - "strings" - "github.com/drone/drone/model" "github.com/russross/meddler" ) @@ -35,41 +33,3 @@ func rebind(query string) string { } return string(rqb) } - -// helper function that converts a simple repsitory list -// to a sql IN statment. -func toList(listof []*model.RepoLite) (string, []interface{}) { - var size = len(listof) - switch { - case meddler.Default == meddler.SQLite && size > 999: - size = 999 - listof = listof[:999] - case size > 15000: - size = 15000 - listof = listof[:15000] - } - var qs = make([]string, size, size) - var in = make([]interface{}, size, size) - for i, repo := range listof { - qs[i] = "?" - in[i] = repo.FullName - } - return strings.Join(qs, ","), in -} - -// helper function that converts a simple repository list -// to a sql IN statement compatible with postgres. -func toListPostgres(listof []*model.RepoLite) (string, []interface{}) { - var size = len(listof) - if size > 15000 { - size = 15000 - listof = listof[:15000] - } - var qs = make([]string, size, size) - var in = make([]interface{}, size, size) - for i, repo := range listof { - qs[i] = "$" + strconv.Itoa(i+1) - in[i] = repo.FullName - } - return strings.Join(qs, ","), in -} diff --git a/store/store.go b/store/store.go index 3b8dfdd36..6e4c23a07 100644 --- a/store/store.go +++ b/store/store.go @@ -18,13 +18,6 @@ type Store interface { // GetUserList gets a list of all users in the system. GetUserList() ([]*model.User, error) - // GetUserFeed gets a user activity feed. - GetUserFeed([]*model.RepoLite) ([]*model.Feed, error) - - // GetUserFeedLatest gets a user activity feed for all repositories including - // only the latest build for each repository. - GetUserFeedLatest(listof []*model.RepoLite) ([]*model.Feed, error) - // GetUserCount gets a count of all users in the system. GetUserCount() (int, error) @@ -43,9 +36,6 @@ type Store interface { // GetRepoName gets a repo by its full name. GetRepoName(string) (*model.Repo, error) - // GetRepoListOf gets the list of enumerated repos in the system. - GetRepoListOf([]*model.RepoLite) ([]*model.Repo, error) - // GetRepoCount gets a count of all repositories in the system. GetRepoCount() (int, error) @@ -162,14 +152,6 @@ func GetUserList(c context.Context) ([]*model.User, error) { return FromContext(c).GetUserList() } -// GetUserFeed gets a user activity feed. -func GetUserFeed(c context.Context, listof []*model.RepoLite, latest bool) ([]*model.Feed, error) { - if latest { - return FromContext(c).GetUserFeedLatest(listof) - } - return FromContext(c).GetUserFeed(listof) -} - // GetUserCount gets a count of all users in the system. func GetUserCount(c context.Context) (int, error) { return FromContext(c).GetUserCount() @@ -199,10 +181,6 @@ func GetRepoOwnerName(c context.Context, owner, name string) (*model.Repo, error return FromContext(c).GetRepoName(owner + "/" + name) } -func GetRepoListOf(c context.Context, listof []*model.RepoLite) ([]*model.Repo, error) { - return FromContext(c).GetRepoListOf(listof) -} - func CreateRepo(c context.Context, repo *model.Repo) error { return FromContext(c).CreateRepo(repo) }