You've already forked woodpecker
							
							
				mirror of
				https://github.com/woodpecker-ci/woodpecker.git
				synced 2025-10-30 23:27:39 +02:00 
			
		
		
		
	moved from datasql to datastore, added unit test for users
This commit is contained in:
		| @@ -1,4 +1,4 @@ | ||||
| package datasql | ||||
| package database | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/drone/drone/shared/model" | ||||
| @@ -25,7 +25,7 @@ func (db *Commitstore) GetCommit(id int64) (*model.Commit, error) { | ||||
| // datastore for the specified repo and sha | ||||
| func (db *Commitstore) GetCommitSha(repo *model.Repo, branch, sha string) (*model.Commit, error) { | ||||
| 	var commit = new(model.Commit) | ||||
| 	var err = meddler.QueryRow(db, commit, commitShaQuery, repo.ID, branch, sha) | ||||
| 	var err = meddler.QueryRow(db, commit, rebind(commitShaQuery), repo.ID, branch, sha) | ||||
| 	return commit, err | ||||
| } | ||||
| 
 | ||||
| @@ -34,7 +34,7 @@ func (db *Commitstore) GetCommitSha(repo *model.Repo, branch, sha string) (*mode | ||||
| // and branch. | ||||
| func (db *Commitstore) GetCommitLast(repo *model.Repo, branch string) (*model.Commit, error) { | ||||
| 	var commit = new(model.Commit) | ||||
| 	var err = meddler.QueryRow(db, commit, commitLastQuery, repo.ID, branch) | ||||
| 	var err = meddler.QueryRow(db, commit, rebind(commitLastQuery), repo.ID, branch) | ||||
| 	return commit, err | ||||
| } | ||||
| 
 | ||||
| @@ -42,7 +42,7 @@ func (db *Commitstore) GetCommitLast(repo *model.Repo, branch string) (*model.Co | ||||
| // from the datastore for the specified repository. | ||||
| func (db *Commitstore) GetCommitList(repo *model.Repo) ([]*model.Commit, error) { | ||||
| 	var commits []*model.Commit | ||||
| 	var err = meddler.QueryAll(db, &commits, commitListQuery) | ||||
| 	var err = meddler.QueryAll(db, &commits, rebind(commitListQuery)) | ||||
| 	return commits, err | ||||
| } | ||||
| 
 | ||||
| @@ -64,14 +64,14 @@ func (db *Commitstore) PutCommit(commit *model.Commit) error { | ||||
| 
 | ||||
| // DelCommit removes the commit from the datastore. | ||||
| func (db *Commitstore) DelCommit(commit *model.Commit) error { | ||||
| 	var _, err = db.Exec(commitDeleteStmt, commit.ID) | ||||
| 	var _, err = db.Exec(rebind(commitDeleteStmt), commit.ID) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| // KillCommits updates all pending or started commits | ||||
| // in the datastore settings the status to killed. | ||||
| func (db *Commitstore) KillCommits() error { | ||||
| 	var _, err = db.Exec(commitKillStmt) | ||||
| 	var _, err = db.Exec(rebind(commitKillStmt)) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										1
									
								
								server/datastore/database/commit_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								server/datastore/database/commit_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| package database | ||||
							
								
								
									
										67
									
								
								server/datastore/database/database.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								server/datastore/database/database.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| package database | ||||
|  | ||||
| import ( | ||||
| 	"database/sql" | ||||
|  | ||||
| 	"github.com/drone/drone/server/datastore" | ||||
| 	"github.com/drone/drone/server/datastore/database/migrate" | ||||
|  | ||||
| 	"github.com/BurntSushi/migration" | ||||
| 	_ "github.com/go-sql-driver/mysql" | ||||
| 	_ "github.com/lib/pq" | ||||
| 	_ "github.com/mattn/go-sqlite3" | ||||
| 	"github.com/russross/meddler" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	driverPostgres = "postgres" | ||||
| 	driverSqlite   = "sqlite3" | ||||
| 	driverMysql    = "mysql" | ||||
| ) | ||||
|  | ||||
| // Connect is a helper function that establishes a new | ||||
| // database connection and auto-generates the database | ||||
| // schema. If the database already exists, it will perform | ||||
| // and update as needed. | ||||
| func Connect(driver, datasource string) (*sql.DB, error) { | ||||
| 	switch driver { | ||||
| 	case driverPostgres: | ||||
| 		meddler.Default = meddler.PostgreSQL | ||||
| 	case driverSqlite: | ||||
| 		meddler.Default = meddler.SQLite | ||||
| 	case driverMysql: | ||||
| 		meddler.Default = meddler.MySQL | ||||
| 	} | ||||
| 	migration.DefaultGetVersion = migrate.GetVersion | ||||
| 	migration.DefaultSetVersion = migrate.SetVersion | ||||
| 	var migrations = []migration.Migrator{ | ||||
| 		migrate.Setup, | ||||
| 	} | ||||
| 	return migration.Open(driver, datasource, migrations) | ||||
| } | ||||
|  | ||||
| // MustConnect is a helper function that create a | ||||
| // new database commention and auto-generates the | ||||
| // database schema. An error causes a panic. | ||||
| func MustConnect(driver, datasource string) *sql.DB { | ||||
| 	db, err := Connect(driver, datasource) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	return db | ||||
| } | ||||
|  | ||||
| // New returns a new DataStore | ||||
| func New(db *sql.DB) datastore.Datastore { | ||||
| 	return struct { | ||||
| 		*Userstore | ||||
| 		*Permstore | ||||
| 		*Repostore | ||||
| 		*Commitstore | ||||
| 	}{ | ||||
| 		NewUserstore(db), | ||||
| 		NewPermstore(db), | ||||
| 		NewRepostore(db), | ||||
| 		NewCommitstore(db), | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										46
									
								
								server/datastore/database/migrate/helper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								server/datastore/database/migrate/helper.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| package migrate | ||||
|  | ||||
| import ( | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/russross/meddler" | ||||
| ) | ||||
|  | ||||
| // transform is a helper function that transforms sql | ||||
| // statements to work with multiple database types. | ||||
| func transform(stmt string) string { | ||||
| 	switch meddler.Default { | ||||
| 	case meddler.MySQL: | ||||
| 		stmt = strings.Replace(stmt, "AUTOINCREMENT", "AUTO_INCREMENT", -1) | ||||
| 	case meddler.PostgreSQL: | ||||
| 		stmt = strings.Replace(stmt, "INTEGER PRIMARY KEY AUTOINCREMENT", "SERIAL PRIMARY KEY", -1) | ||||
| 		stmt = strings.Replace(stmt, "BLOB", "BYTEA", -1) | ||||
| 	} | ||||
| 	return stmt | ||||
| } | ||||
|  | ||||
| // rebind is a helper function that changes the sql | ||||
| // bind type from ? to $ for postgres queries. | ||||
| func rebind(query string) string { | ||||
| 	if meddler.Default != meddler.PostgreSQL { | ||||
| 		return query | ||||
| 	} | ||||
|  | ||||
| 	qb := []byte(query) | ||||
| 	// Add space enough for 10 params before we have to allocate | ||||
| 	rqb := make([]byte, 0, len(qb)+10) | ||||
| 	j := 1 | ||||
| 	for _, b := range qb { | ||||
| 		if b == '?' { | ||||
| 			rqb = append(rqb, '$') | ||||
| 			for _, b := range strconv.Itoa(j) { | ||||
| 				rqb = append(rqb, byte(b)) | ||||
| 			} | ||||
| 			j++ | ||||
| 		} else { | ||||
| 			rqb = append(rqb, b) | ||||
| 		} | ||||
| 	} | ||||
| 	return string(rqb) | ||||
| } | ||||
							
								
								
									
										118
									
								
								server/datastore/database/migrate/setup.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								server/datastore/database/migrate/setup.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| package migrate | ||||
|  | ||||
| import ( | ||||
| 	"github.com/BurntSushi/migration" | ||||
| ) | ||||
|  | ||||
| // Setup is the database migration function that | ||||
| // will setup the initial SQL database structure. | ||||
| func Setup(tx migration.LimitedTx) error { | ||||
| 	var stmts = []string{ | ||||
| 		blobTable, | ||||
| 		userTable, | ||||
| 		repoTable, | ||||
| 		permTable, | ||||
| 		commitTable, | ||||
| 	} | ||||
| 	for _, stmt := range stmts { | ||||
| 		_, err := tx.Exec(transform(stmt)) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| var userTable = ` | ||||
| CREATE TABLE IF NOT EXISTS users ( | ||||
| 	 user_id           INTEGER PRIMARY KEY AUTOINCREMENT | ||||
| 	,user_remote       VARCHAR(255) | ||||
| 	,user_login        VARCHAR(255) | ||||
| 	,user_access       VARCHAR(255) | ||||
| 	,user_secret       VARCHAR(255) | ||||
| 	,user_name         VARCHAR(255) | ||||
| 	,user_email        VARCHAR(255) | ||||
| 	,user_gravatar     VARCHAR(255) | ||||
| 	,user_token        VARCHAR(255) | ||||
| 	,user_admin        BOOLEAN | ||||
| 	,user_active       BOOLEAN | ||||
| 	,user_syncing      BOOLEAN | ||||
| 	,user_created      INTEGER | ||||
| 	,user_updated      INTEGER | ||||
| 	,user_synced       INTEGER | ||||
| 	,UNIQUE(user_token) | ||||
| 	,UNIQUE(user_remote, user_login) | ||||
| ); | ||||
| ` | ||||
|  | ||||
| var permTable = ` | ||||
| CREATE TABLE IF NOT EXISTS perms ( | ||||
| 	 perm_id           INTEGER PRIMARY KEY AUTOINCREMENT | ||||
| 	,user_id           INTEGER | ||||
| 	,repo_id           INTEGER | ||||
| 	,perm_read         BOOLEAN | ||||
| 	,perm_write        BOOLEAN | ||||
| 	,perm_admin        BOOLEAN | ||||
| 	,perm_created      INTEGER | ||||
| 	,perm_updated      INTEGER | ||||
| 	,UNIQUE (repo_id, user_id) | ||||
| ); | ||||
| ` | ||||
|  | ||||
| var repoTable = ` | ||||
| CREATE TABLE IF NOT EXISTS repos ( | ||||
| 	 repo_id           INTEGER PRIMARY KEY AUTOINCREMENT | ||||
| 	,user_id           INTEGER | ||||
| 	,repo_remote       VARCHAR(255) | ||||
| 	,repo_host         VARCHAR(255) | ||||
| 	,repo_owner        VARCHAR(255) | ||||
| 	,repo_name         VARCHAR(255) | ||||
| 	,repo_url          VARCHAR(1024) | ||||
| 	,repo_clone_url    VARCHAR(255) | ||||
| 	,repo_git_url      VARCHAR(255) | ||||
| 	,repo_ssh_url      VARCHAR(255) | ||||
| 	,repo_active       BOOLEAN | ||||
| 	,repo_private      BOOLEAN | ||||
| 	,repo_privileged   BOOLEAN | ||||
| 	,repo_post_commit  BOOLEAN | ||||
| 	,repo_pull_request BOOLEAN | ||||
| 	,repo_public_key   BLOB | ||||
| 	,repo_private_key  BLOB | ||||
| 	,repo_params       BLOB | ||||
| 	,repo_timeout      INTEGER | ||||
| 	,repo_created      INTEGER | ||||
| 	,repo_updated      INTEGER | ||||
| 	,UNIQUE(repo_host, repo_owner, repo_name) | ||||
| ); | ||||
| ` | ||||
|  | ||||
| var commitTable = ` | ||||
| CREATE TABLE IF NOT EXISTS commits ( | ||||
| 	 commit_id         INTEGER PRIMARY KEY AUTOINCREMENT | ||||
| 	,repo_id           INTEGER | ||||
| 	,commit_status     VARCHAR(255) | ||||
| 	,commit_started    INTEGER | ||||
| 	,commit_finished   INTEGER | ||||
| 	,commit_duration   INTEGER | ||||
| 	,commit_sha        VARCHAR(255) | ||||
| 	,commit_branch     VARCHAR(255) | ||||
| 	,commit_pr         VARCHAR(255) | ||||
| 	,commit_author     VARCHAR(255) | ||||
| 	,commit_gravatar   VARCHAR(255) | ||||
| 	,commit_timestamp  VARCHAR(255) | ||||
| 	,commit_message    VARCHAR(255) | ||||
| 	,commit_yaml       BLOB | ||||
| 	,commit_created    INTEGER | ||||
| 	,commit_updated    INTEGER | ||||
| 	,UNIQUE(commit_sha, commit_branch, repo_id) | ||||
| ); | ||||
| ` | ||||
|  | ||||
| var blobTable = ` | ||||
| CREATE TABLE IF NOT EXISTS blobs ( | ||||
| 	 blob_id      INTEGER PRIMARY KEY AUTOINCREMENT | ||||
| 	,blob_path    VARCHAR(1024) | ||||
| 	,blob_data    BLOB | ||||
| 	,UNIQUE(blob_path) | ||||
| ); | ||||
| ` | ||||
							
								
								
									
										57
									
								
								server/datastore/database/migrate/version.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								server/datastore/database/migrate/version.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| package migrate | ||||
|  | ||||
| import ( | ||||
| 	"github.com/BurntSushi/migration" | ||||
| ) | ||||
|  | ||||
| // GetVersion gets the migration version from the database, | ||||
| // creating the migration table if it does not already exist. | ||||
| func GetVersion(tx migration.LimitedTx) (int, error) { | ||||
| 	v, err := getVersion(tx) | ||||
| 	if err != nil { | ||||
| 		if err := createVersionTable(tx); err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 		return getVersion(tx) | ||||
| 	} | ||||
| 	return v, nil | ||||
| } | ||||
|  | ||||
| // SetVersion sets the migration version in the database, | ||||
| // creating the migration table if it does not already exist. | ||||
| func SetVersion(tx migration.LimitedTx, version int) error { | ||||
| 	if err := setVersion(tx, version); err != nil { | ||||
| 		if err := createVersionTable(tx); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		return setVersion(tx, version) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // setVersion updates the migration version in the database. | ||||
| func setVersion(tx migration.LimitedTx, version int) error { | ||||
| 	_, err := tx.Exec(rebind("UPDATE migration_version SET version = ?"), version) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // getVersion gets the migration version in the database. | ||||
| func getVersion(tx migration.LimitedTx) (int, error) { | ||||
| 	var version int | ||||
| 	row := tx.QueryRow("SELECT version FROM migration_version") | ||||
| 	if err := row.Scan(&version); err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return version, nil | ||||
| } | ||||
|  | ||||
| // createVersionTable creates the version table and inserts the | ||||
| // initial value (0) into the database. | ||||
| func createVersionTable(tx migration.LimitedTx) error { | ||||
| 	_, err := tx.Exec("CREATE TABLE migration_version ( version INTEGER )") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	_, err = tx.Exec("INSERT INTO migration_version (version) VALUES (0)") | ||||
| 	return err | ||||
| } | ||||
| @@ -1,4 +1,4 @@ | ||||
| package datasql | ||||
| package database | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/drone/drone/shared/model" | ||||
| @@ -17,7 +17,7 @@ func NewPermstore(db meddler.DB) *Permstore { | ||||
| // the datastore for the given repository. | ||||
| func (db *Repostore) GetPerm(user *model.User, repo *model.Repo) (*model.Perm, error) { | ||||
| 	var perm = new(model.Perm) | ||||
| 	var err = meddler.QueryRow(db, perm, permQuery, user.ID, repo.ID) | ||||
| 	var err = meddler.QueryRow(db, perm, rebind(permQuery), user.ID, repo.ID) | ||||
| 	return perm, err | ||||
| } | ||||
| 
 | ||||
| @@ -33,7 +33,7 @@ func (db *Repostore) PutPerm(perm *model.Perm) error { | ||||
| 
 | ||||
| // DelPerm removes permission from the datastore. | ||||
| func (db *Repostore) DelPerm(perm *model.Perm) error { | ||||
| 	var _, err = db.Exec(permDeleteStmt, perm.ID) | ||||
| 	var _, err = db.Exec(rebind(permDeleteStmt), perm.ID) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										1
									
								
								server/datastore/database/perm_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								server/datastore/database/perm_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| package database | ||||
| @@ -1,4 +1,4 @@ | ||||
| package datasql | ||||
| package database | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/drone/drone/shared/model" | ||||
| @@ -25,7 +25,7 @@ func (db *Repostore) GetRepo(id int64) (*model.Repo, error) { | ||||
| // for the specified remote, owner and name. | ||||
| func (db *Repostore) GetRepoName(remote, owner, name string) (*model.Repo, error) { | ||||
| 	var repo = new(model.Repo) | ||||
| 	var err = meddler.QueryRow(db, repo, repoNameQuery, remote, owner, name) | ||||
| 	var err = meddler.QueryRow(db, repo, rebind(repoNameQuery), remote, owner, name) | ||||
| 	return repo, err | ||||
| } | ||||
| 
 | ||||
| @@ -33,7 +33,7 @@ func (db *Repostore) GetRepoName(remote, owner, name string) (*model.Repo, error | ||||
| // the datastore accessible by the given user ID. | ||||
| func (db *Repostore) GetRepoList(user *model.User) ([]*model.Repo, error) { | ||||
| 	var repos []*model.Repo | ||||
| 	var err = meddler.QueryAll(db, &repos, repoListQuery) | ||||
| 	var err = meddler.QueryAll(db, &repos, rebind(repoListQuery)) | ||||
| 	return repos, err | ||||
| } | ||||
| 
 | ||||
| @@ -49,7 +49,7 @@ func (db *Repostore) PutRepo(repo *model.Repo) error { | ||||
| 
 | ||||
| // DelRepo removes the repo from the datastore. | ||||
| func (db *Repostore) DelRepo(repo *model.Repo) error { | ||||
| 	var _, err = db.Exec(repoDeleteStmt, repo.ID) | ||||
| 	var _, err = db.Exec(rebind(repoDeleteStmt), repo.ID) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										1
									
								
								server/datastore/database/repo_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								server/datastore/database/repo_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| package database | ||||
| @@ -1,4 +1,4 @@ | ||||
| package datasql | ||||
| package database | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/drone/drone/shared/model" | ||||
| @@ -15,7 +15,7 @@ func NewUserstore(db meddler.DB) *Userstore { | ||||
| 
 | ||||
| // GetUser retrieves a specific user from the | ||||
| // datastore for the given ID. | ||||
| func (db *Repostore) GetUser(id int64) (*model.User, error) { | ||||
| func (db *Userstore) GetUser(id int64) (*model.User, error) { | ||||
| 	var usr = new(model.User) | ||||
| 	var err = meddler.Load(db, userTable, usr, id) | ||||
| 	return usr, err | ||||
| @@ -23,41 +23,41 @@ func (db *Repostore) GetUser(id int64) (*model.User, error) { | ||||
| 
 | ||||
| // GetUserLogin retrieves a user from the datastore | ||||
| // for the specified remote and login name. | ||||
| func (db *Repostore) GetUserLogin(remote, login string) (*model.User, error) { | ||||
| func (db *Userstore) GetUserLogin(remote, login string) (*model.User, error) { | ||||
| 	var usr = new(model.User) | ||||
| 	var err = meddler.QueryRow(db, usr, userLoginQuery) | ||||
| 	var err = meddler.QueryRow(db, usr, rebind(userLoginQuery), remote, login) | ||||
| 	return usr, err | ||||
| } | ||||
| 
 | ||||
| // GetUserToken retrieves a user from the datastore | ||||
| // with the specified token. | ||||
| func (db *Repostore) GetUserToken(token string) (*model.User, error) { | ||||
| func (db *Userstore) GetUserToken(token string) (*model.User, error) { | ||||
| 	var usr = new(model.User) | ||||
| 	var err = meddler.QueryRow(db, usr, userTokenQuery) | ||||
| 	var err = meddler.QueryRow(db, usr, rebind(userTokenQuery), token) | ||||
| 	return usr, err | ||||
| } | ||||
| 
 | ||||
| // GetUserList retrieves a list of all users from | ||||
| // the datastore that are registered in the system. | ||||
| func (db *Repostore) GetUserList() ([]*model.User, error) { | ||||
| func (db *Userstore) GetUserList() ([]*model.User, error) { | ||||
| 	var users []*model.User | ||||
| 	var err = meddler.QueryAll(db, &users, userListQuery) | ||||
| 	var err = meddler.QueryAll(db, &users, rebind(userListQuery)) | ||||
| 	return users, err | ||||
| } | ||||
| 
 | ||||
| // PostUser saves a User in the datastore. | ||||
| func (db *Repostore) PostUser(user *model.User) error { | ||||
| func (db *Userstore) PostUser(user *model.User) error { | ||||
| 	return meddler.Save(db, userTable, user) | ||||
| } | ||||
| 
 | ||||
| // PutUser saves a user in the datastore. | ||||
| func (db *Repostore) PutUser(user *model.User) error { | ||||
| func (db *Userstore) PutUser(user *model.User) error { | ||||
| 	return meddler.Save(db, userTable, user) | ||||
| } | ||||
| 
 | ||||
| // DelUser removes the user from the datastore. | ||||
| func (db *Repostore) DelUser(user *model.User) error { | ||||
| 	var _, err = db.Exec(userDeleteStmt, user.ID) | ||||
| func (db *Userstore) DelUser(user *model.User) error { | ||||
| 	var _, err = db.Exec(rebind(userDeleteStmt), user.ID) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										203
									
								
								server/datastore/database/user_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								server/datastore/database/user_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | ||||
| package database | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/drone/drone/shared/model" | ||||
| 	"github.com/franela/goblin" | ||||
| ) | ||||
|  | ||||
| func TestPackagestore(t *testing.T) { | ||||
| 	db := MustConnect("sqlite3", ":memory:") | ||||
| 	us := NewUserstore(db) | ||||
| 	defer db.Close() | ||||
|  | ||||
| 	g := goblin.Goblin(t) | ||||
| 	g.Describe("Userstore", func() { | ||||
|  | ||||
| 		// before each test be sure to purge the package | ||||
| 		// table data from the database. | ||||
| 		g.BeforeEach(func() { | ||||
| 			db.Exec("DELETE FROM users") | ||||
| 		}) | ||||
|  | ||||
| 		g.It("Should Put a User", func() { | ||||
| 			user := model.User{ | ||||
| 				Login:  "joe", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Joe Sixpack", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "e42080dddf012c718e476da161d21ad5", | ||||
| 			} | ||||
| 			err := us.PostUser(&user) | ||||
| 			g.Assert(err == nil).IsTrue() | ||||
| 			g.Assert(user.ID != 0).IsTrue() | ||||
| 		}) | ||||
|  | ||||
| 		g.It("Should Post a User", func() { | ||||
| 			user := model.User{ | ||||
| 				Login:  "joe", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Joe Sixpack", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "e42080dddf012c718e476da161d21ad5", | ||||
| 			} | ||||
| 			err := us.PostUser(&user) | ||||
| 			g.Assert(err == nil).IsTrue() | ||||
| 			g.Assert(user.ID != 0).IsTrue() | ||||
| 		}) | ||||
|  | ||||
| 		g.It("Should Get a User", func() { | ||||
| 			user := model.User{ | ||||
| 				Login:    "joe", | ||||
| 				Remote:   "github.com", | ||||
| 				Access:   "f0b461ca586c27872b43a0685cbc2847", | ||||
| 				Secret:   "976f22a5eef7caacb7e678d6c52f49b1", | ||||
| 				Name:     "Joe Sixpack", | ||||
| 				Email:    "foo@bar.com", | ||||
| 				Gravatar: "b9015b0857e16ac4d94a0ffd9a0b79c8", | ||||
| 				Token:    "e42080dddf012c718e476da161d21ad5", | ||||
| 				Active:   true, | ||||
| 				Admin:    true, | ||||
| 				Created:  1398065343, | ||||
| 				Updated:  1398065344, | ||||
| 				Synced:   1398065345, | ||||
| 			} | ||||
| 			us.PostUser(&user) | ||||
| 			getuser, err := us.GetUser(user.ID) | ||||
| 			g.Assert(err == nil).IsTrue() | ||||
| 			g.Assert(user.ID).Equal(getuser.ID) | ||||
| 			g.Assert(user.Login).Equal(getuser.Login) | ||||
| 			g.Assert(user.Remote).Equal(getuser.Remote) | ||||
| 			g.Assert(user.Access).Equal(getuser.Access) | ||||
| 			g.Assert(user.Secret).Equal(getuser.Secret) | ||||
| 			g.Assert(user.Name).Equal(getuser.Name) | ||||
| 			g.Assert(user.Email).Equal(getuser.Email) | ||||
| 			g.Assert(user.Gravatar).Equal(getuser.Gravatar) | ||||
| 			g.Assert(user.Token).Equal(getuser.Token) | ||||
| 			g.Assert(user.Active).Equal(getuser.Active) | ||||
| 			g.Assert(user.Admin).Equal(getuser.Admin) | ||||
| 			g.Assert(user.Created).Equal(getuser.Created) | ||||
| 			g.Assert(user.Updated).Equal(getuser.Updated) | ||||
| 			g.Assert(user.Synced).Equal(getuser.Synced) | ||||
| 		}) | ||||
|  | ||||
| 		g.It("Should Get a User By Login", func() { | ||||
| 			user := model.User{ | ||||
| 				Login:  "joe", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Joe Sixpack", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "e42080dddf012c718e476da161d21ad5", | ||||
| 			} | ||||
| 			us.PostUser(&user) | ||||
| 			getuser, err := us.GetUserLogin(user.Remote, user.Login) | ||||
| 			g.Assert(err == nil).IsTrue() | ||||
| 			g.Assert(user.ID).Equal(getuser.ID) | ||||
| 			g.Assert(user.Login).Equal(getuser.Login) | ||||
| 			g.Assert(user.Remote).Equal(getuser.Remote) | ||||
| 		}) | ||||
|  | ||||
| 		g.It("Should Get a User By Token", func() { | ||||
| 			user := model.User{ | ||||
| 				Login:  "joe", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Joe Sixpack", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "e42080dddf012c718e476da161d21ad5", | ||||
| 			} | ||||
| 			us.PostUser(&user) | ||||
| 			getuser, err := us.GetUserToken(user.Token) | ||||
| 			g.Assert(err == nil).IsTrue() | ||||
| 			g.Assert(user.ID).Equal(getuser.ID) | ||||
| 			g.Assert(user.Token).Equal(getuser.Token) | ||||
| 		}) | ||||
|  | ||||
| 		g.It("Should Enforce Unique User Token", func() { | ||||
| 			user1 := model.User{ | ||||
| 				Login:  "jane", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Jane Doe", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "e42080dddf012c718e476da161d21ad5", | ||||
| 			} | ||||
| 			user2 := model.User{ | ||||
| 				Login:  "joe", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Joe Sixpack", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "e42080dddf012c718e476da161d21ad5", | ||||
| 			} | ||||
| 			err1 := us.PostUser(&user1) | ||||
| 			err2 := us.PostUser(&user2) | ||||
| 			g.Assert(err1 == nil).IsTrue() | ||||
| 			g.Assert(err2 == nil).IsFalse() | ||||
| 		}) | ||||
|  | ||||
| 		g.It("Should Enforce Unique User Remote and Login", func() { | ||||
| 			user1 := model.User{ | ||||
| 				Login:  "joe", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Joe Sixpack", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "e42080dddf012c718e476da161d21ad5", | ||||
| 			} | ||||
| 			user2 := model.User{ | ||||
| 				Login:  "joe", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Joe Sixpack", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "ab20g0ddaf012c744e136da16aa21ad9", | ||||
| 			} | ||||
| 			err1 := us.PostUser(&user1) | ||||
| 			err2 := us.PostUser(&user2) | ||||
| 			g.Assert(err1 == nil).IsTrue() | ||||
| 			g.Assert(err2 == nil).IsFalse() | ||||
| 		}) | ||||
|  | ||||
| 		g.It("Should Get a User List", func() { | ||||
| 			user1 := model.User{ | ||||
| 				Login:  "jane", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Jane Doe", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "ab20g0ddaf012c744e136da16aa21ad9", | ||||
| 			} | ||||
| 			user2 := model.User{ | ||||
| 				Login:  "joe", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Joe Sixpack", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "e42080dddf012c718e476da161d21ad5", | ||||
| 			} | ||||
| 			us.PostUser(&user1) | ||||
| 			us.PostUser(&user2) | ||||
| 			users, err := us.GetUserList() | ||||
| 			g.Assert(err == nil).IsTrue() | ||||
| 			g.Assert(len(users)).Equal(2) | ||||
| 			g.Assert(users[0].Login).Equal(user1.Login) | ||||
| 			g.Assert(users[0].Remote).Equal(user1.Remote) | ||||
| 			g.Assert(users[0].Name).Equal(user1.Name) | ||||
| 			g.Assert(users[0].Email).Equal(user1.Email) | ||||
| 			g.Assert(users[0].Token).Equal(user1.Token) | ||||
| 		}) | ||||
|  | ||||
| 		g.It("Should Del a User", func() { | ||||
| 			user := model.User{ | ||||
| 				Login:  "joe", | ||||
| 				Remote: "github.com", | ||||
| 				Name:   "Joe Sixpack", | ||||
| 				Email:  "foo@bar.com", | ||||
| 				Token:  "e42080dddf012c718e476da161d21ad5", | ||||
| 			} | ||||
| 			us.PostUser(&user) | ||||
| 			_, err1 := us.GetUser(user.ID) | ||||
| 			err2 := us.DelUser(&user) | ||||
| 			_, err3 := us.GetUser(user.ID) | ||||
| 			g.Assert(err1 == nil).IsTrue() | ||||
| 			g.Assert(err2 == nil).IsTrue() | ||||
| 			g.Assert(err3 == nil).IsFalse() | ||||
| 		}) | ||||
|  | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										32
									
								
								server/datastore/database/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								server/datastore/database/util.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| package database | ||||
|  | ||||
| import ( | ||||
| 	"strconv" | ||||
|  | ||||
| 	"github.com/russross/meddler" | ||||
| ) | ||||
|  | ||||
| // rebind is a helper function that changes the sql | ||||
| // bind type from ? to $ for postgres queries. | ||||
| func rebind(query string) string { | ||||
| 	if meddler.Default != meddler.PostgreSQL { | ||||
| 		return query | ||||
| 	} | ||||
|  | ||||
| 	qb := []byte(query) | ||||
| 	// Add space enough for 10 params before we have to allocate | ||||
| 	rqb := make([]byte, 0, len(qb)+10) | ||||
| 	j := 1 | ||||
| 	for _, b := range qb { | ||||
| 		if b == '?' { | ||||
| 			rqb = append(rqb, '$') | ||||
| 			for _, b := range strconv.Itoa(j) { | ||||
| 				rqb = append(rqb, byte(b)) | ||||
| 			} | ||||
| 			j++ | ||||
| 		} else { | ||||
| 			rqb = append(rqb, b) | ||||
| 		} | ||||
| 	} | ||||
| 	return string(rqb) | ||||
| } | ||||
| @@ -1 +0,0 @@ | ||||
| package datasql | ||||
| @@ -1,54 +0,0 @@ | ||||
| package datasql | ||||
|  | ||||
| import ( | ||||
| 	"database/sql" | ||||
|  | ||||
| 	"github.com/drone/drone/server/blobstore/blobsql" | ||||
| 	"github.com/drone/drone/server/datastore" | ||||
| 	"github.com/drone/drone/shared/model" | ||||
|  | ||||
| 	"github.com/astaxie/beego/orm" | ||||
| 	_ "github.com/mattn/go-sqlite3" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	driverPostgres = "postgres" | ||||
| 	driverSqlite   = "sqlite3" | ||||
| 	driverMysql    = "mysql" | ||||
| 	databaseName   = "default" | ||||
| ) | ||||
|  | ||||
| // Connect is a helper function that establishes a new | ||||
| // database connection and auto-generates the database | ||||
| // schema. If the database already exists, it will perform | ||||
| // and update as needed. | ||||
| func Connect(driver, datasource string) (*sql.DB, error) { | ||||
| 	defer orm.ResetModelCache() | ||||
| 	orm.RegisterDriver(driverSqlite, orm.DR_Sqlite) | ||||
| 	orm.RegisterDataBase(databaseName, driver, datasource) | ||||
| 	orm.RegisterModel(new(model.User)) | ||||
| 	orm.RegisterModel(new(model.Perm)) | ||||
| 	orm.RegisterModel(new(model.Repo)) | ||||
| 	orm.RegisterModel(new(model.Commit)) | ||||
| 	orm.RegisterModel(new(blobsql.Blob)) | ||||
| 	var err = orm.RunSyncdb(databaseName, true, true) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return orm.GetDB(databaseName) | ||||
| } | ||||
|  | ||||
| // New returns a new DataStore | ||||
| func New(db *sql.DB) datastore.Datastore { | ||||
| 	return struct { | ||||
| 		*Userstore | ||||
| 		*Permstore | ||||
| 		*Repostore | ||||
| 		*Commitstore | ||||
| 	}{ | ||||
| 		NewUserstore(db), | ||||
| 		NewPermstore(db), | ||||
| 		NewRepostore(db), | ||||
| 		NewCommitstore(db), | ||||
| 	} | ||||
| } | ||||
| @@ -1 +0,0 @@ | ||||
| package datasql | ||||
| @@ -1 +0,0 @@ | ||||
| package datasql | ||||
| @@ -1 +0,0 @@ | ||||
| package datasql | ||||
		Reference in New Issue
	
	Block a user