diff --git a/app/controllers/gorp.go b/app/controllers/gorp.go index 6744306..5678fe4 100644 --- a/app/controllers/gorp.go +++ b/app/controllers/gorp.go @@ -25,9 +25,15 @@ func InitDB() { appTableMap := Dbm.AddTableWithName(models.App{}, "app") appTableMap.SetKeys(true, "Id") appTableMap.ColMap("ApiToken").SetUnique(true) + appTableMap.ColMap("FileId").SetUnique(true) bundleTableMap := Dbm.AddTableWithName(models.Bundle{}, "bundle") bundleTableMap.SetKeys(true, "Id") + bundleTableMap.ColMap("FileId").SetUnique(true) + + revisionTableMap := Dbm.AddTableWithName(models.Revision{}, "revision") + revisionTableMap.SetKeys(true, "Id") + revisionTableMap.SetUniqueTogether("app_id", "platform_type", "bundle_version") authorityTableMap := Dbm.AddTableWithName(models.Authority{}, "authority") authorityTableMap.SetKeys(true, "Id") @@ -39,7 +45,10 @@ func InitDB() { auditTableMap.SetKeys(true, "Id") Dbm.TraceOn("[gorp]", revel.INFO) - Dbm.CreateTablesIfNotExists() + err := Dbm.CreateTablesIfNotExists() + if err != nil { + panic(err) + } } func getDbm() *gorp.DbMap { diff --git a/app/models/app.go b/app/models/app.go index ae87601..76f1fc6 100644 --- a/app/models/app.go +++ b/app/models/app.go @@ -3,6 +3,7 @@ package models import ( "crypto/hmac" "crypto/sha256" + "database/sql" "encoding/hex" "fmt" "strings" @@ -77,13 +78,42 @@ func (app *App) Authorities(txn gorp.SqlExecutor) ([]*Authority, error) { return authorities, nil } -func (app *App) GetMaxRevisionByBundleVersion(txn gorp.SqlExecutor, bundleVersion string) (int, error) { - revision, err := txn.SelectInt( - "SELECT IFNULL(MAX(revision), 0) FROM bundle WHERE app_id = ? AND bundle_version = ?", +func (app *App) IncrementRevision(txn gorp.SqlExecutor, platformType BundlePlatformType, bundleVersion string) (int, error) { + revision, err := GetMaxRevision( + txn, app.Id, + platformType, bundleVersion, ) - return int(revision), err + + if err == sql.ErrNoRows { + var maxRevision int64 + maxRevision, err = txn.SelectInt( + "SELECT IFNULL(MAX(revision), 0) FROM bundle WHERE app_id = ? AND platform_type = ? AND bundle_version = ?", + app.Id, + platformType, + bundleVersion, + ) + if err != nil { + return 0, err + } + maxRevision++ + revision = &Revision{ + AppId: app.Id, + PlatformType: platformType, + BundleVersion: bundleVersion, + MaxRevision: int(maxRevision), + } + err = revision.Save(txn) + } else if err == nil { + revision.MaxRevision++ + err = revision.Update(txn) + } + + if err != nil { + return 0, err + } + return revision.MaxRevision, err } func NewToken() string { @@ -227,13 +257,13 @@ func (app *App) CreateBundle(dbm *gorp.DbMap, s *GoogleService, bundle *Bundle) // increment revision number & save application information err = Transact(dbm, func(txn gorp.SqlExecutor) error { - maxRevision, err := app.GetMaxRevisionByBundleVersion(txn, bundleInfo.Version) + nextRevision, err := app.IncrementRevision(txn, bundle.PlatformType, bundleInfo.Version) if err != nil { return err } - bundle.Revision = maxRevision + 1 + bundle.Revision = nextRevision bundle.FileName = bundle.BuildFileName() - return bundle.Save(txn) + return nil }) if err != nil { panic(err) @@ -249,7 +279,7 @@ func (app *App) CreateBundle(dbm *gorp.DbMap, s *GoogleService, bundle *Bundle) // update FileId bundle.FileId = driveFile.Id return Transact(dbm, func(txn gorp.SqlExecutor) error { - return bundle.Update(txn) + return bundle.Save(txn) }) } diff --git a/app/models/revision.go b/app/models/revision.go new file mode 100644 index 0000000..3a82e39 --- /dev/null +++ b/app/models/revision.go @@ -0,0 +1,37 @@ +package models + +import ( + "github.com/coopernurse/gorp" +) + +type Revision struct { + Id int `db:"id"` + AppId int `db:"app_id"` + PlatformType BundlePlatformType `db:"platform_type"` + BundleVersion string `db:"bundle_version"` + MaxRevision int `db:"max_revision"` +} + +func GetMaxRevision(txn gorp.SqlExecutor, appId int, platformType BundlePlatformType, bundleVersion string) (*Revision, error) { + var revision Revision + err := txn.SelectOne( + &revision, + "SELECT * FROM revision WHERE app_id = ? AND platform_type = ? AND bundle_version = ?", + appId, + platformType, + bundleVersion, + ) + if err != nil { + return nil, err + } + return &revision, nil +} + +func (r *Revision) Save(txn gorp.SqlExecutor) error { + return txn.Insert(r) +} + +func (r *Revision) Update(txn gorp.SqlExecutor) error { + _, err := txn.Update(r) + return err +}