From 0a91b19b5c03c9cdad8d2f64a98e2a10c2e13494 Mon Sep 17 00:00:00 2001 From: Patrick Nagurny Date: Tue, 14 Jan 2020 14:14:16 -0500 Subject: [PATCH 1/3] add budget feature --- core/api/api.go | 5 ++ core/api/budget.go | 149 +++++++++++++++++++++++++++++++++++++ core/api/routes.go | 3 + core/model/budget.go | 58 +++++++++++++++ core/model/db/budget.go | 117 +++++++++++++++++++++++++++++ core/model/db/db.go | 1 + core/model/model.go | 1 + core/model/types/budget.go | 17 +++++ indexes.sql | 3 +- migrations/migrate3.go | 105 ++++++++++++++++++++++++++ schema.sql | 2 + 11 files changed, 460 insertions(+), 1 deletion(-) create mode 100644 core/api/budget.go create mode 100644 core/model/budget.go create mode 100644 core/model/db/budget.go create mode 100644 core/model/types/budget.go create mode 100644 migrations/migrate3.go diff --git a/core/api/api.go b/core/api/api.go index 2b4ef44..6df338e 100644 --- a/core/api/api.go +++ b/core/api/api.go @@ -7,6 +7,11 @@ import ( /** * Changelog * + * 1.4.0 + * - add `GET /orgs/:orgId/budget` + * - add `POST /orgs/:orgId/budget` + * - add `DELETE /orgs/:orgId/budget` + * * 1.3.0 * - add org.timezone * diff --git a/core/api/budget.go b/core/api/budget.go new file mode 100644 index 0000000..d763952 --- /dev/null +++ b/core/api/budget.go @@ -0,0 +1,149 @@ +package api + +import ( + "github.com/ant0ine/go-json-rest/rest" + "github.com/openaccounting/oa-server/core/model" + "github.com/openaccounting/oa-server/core/model/types" + "net/http" +) + +/** + * @api {get} /orgs/:orgId/budget Get Budget + * @apiVersion 1.4.0 + * @apiName GetBudget + * @apiGroup Budget + * + * @apiHeader {String} Authorization HTTP Basic Auth + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning + * + * @apiSuccess {String} orgId Id of the Org. + * @apiSuccess {Date} inserted Date Transaction was created + * @apiSuccess {Object[]} items Array of Budget Items + * + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * [ + * { + * "orgId": "11111111111111111111111111111111", + * "inserted": "2020-01-13T20:12:29.720Z", + * "items": [ + * { + * "accountId": "11111111111111111111111111111111", + * "amount": 35000, + * }, + * { + * "accountId": "22222222222222222222222222222222", + * "amount": 55000 + * } + * ] + * } + * ] + * + * @apiUse NotAuthorizedError + * @apiUse InternalServerError + */ +func GetBudget(w rest.ResponseWriter, r *rest.Request) { + user := r.Env["USER"].(*types.User) + orgId := r.PathParam("orgId") + + budget, err := model.Instance.GetBudget(orgId, user.Id) + + if err != nil { + rest.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.WriteJson(&budget) +} + +/** + * @api {post} /orgs/:orgId/budget Create a Budget + * @apiVersion 1.4.0 + * @apiName PostBudget + * @apiGroup Budget + * + * @apiHeader {String} Authorization HTTP Basic Auth + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning + * + * @apiParam {Object[]} items Array of Budget Items. + * @apiParam {String} items.accountId Id of Expense Account + * @apiParam {Number} items.amount Amount budgeted + * + * @apiSuccess {String} orgId Id of the Org. + * @apiSuccess {Date} inserted Date Transaction was created + * @apiSuccess {Object[]} items Array of Budget Items + * + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * [ + * { + * "orgId": "11111111111111111111111111111111", + * "inserted": "2020-01-13T20:12:29.720Z", + * "items": [ + * { + * "accountId": "11111111111111111111111111111111", + * "amount": 35000, + * }, + * { + * "accountId": "22222222222222222222222222222222", + * "amount": 55000 + * } + * ] + * } + * ] + * + * @apiUse NotAuthorizedError + * @apiUse InternalServerError + */ +func PostBudget(w rest.ResponseWriter, r *rest.Request) { + user := r.Env["USER"].(*types.User) + orgId := r.PathParam("orgId") + + budget := types.Budget{} + err := r.DecodeJsonPayload(&budget) + + if err != nil { + rest.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + budget.OrgId = orgId + + err = model.Instance.CreateBudget(&budget, user.Id) + + if err != nil { + rest.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.WriteJson(budget) +} + +/** + * @api {delete} /orgs/:orgId/budget Delete Budget + * @apiVersion 1.4.0 + * @apiName DeleteBudget + * @apiGroup Budget + * + * @apiHeader {String} Authorization HTTP Basic Auth + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning + * + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * + * @apiUse NotAuthorizedError + * @apiUse InternalServerError + */ +func DeleteBudget(w rest.ResponseWriter, r *rest.Request) { + user := r.Env["USER"].(*types.User) + orgId := r.PathParam("orgId") + + err := model.Instance.DeleteBudget(orgId, user.Id) + + if err != nil { + rest.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) +} diff --git a/core/api/routes.go b/core/api/routes.go index c22ad60..648b69b 100644 --- a/core/api/routes.go +++ b/core/api/routes.go @@ -46,5 +46,8 @@ func GetRouter(auth *AuthMiddleware, prefix string) (rest.App, error) { rest.Put(prefix+"/orgs/:orgId/invites/:inviteId", auth.RequireAuth(PutInvite)), rest.Delete(prefix+"/orgs/:orgId/invites/:inviteId", auth.RequireAuth(DeleteInvite)), rest.Get(prefix+"/health-check", GetSystemHealthStatus), + rest.Get(prefix+"/orgs/:orgId/budget", auth.RequireAuth(GetBudget)), + rest.Post(prefix+"/orgs/:orgId/budget", auth.RequireAuth(PostBudget)), + rest.Delete(prefix+"/orgs/:orgId/budget", auth.RequireAuth(DeleteBudget)), ) } diff --git a/core/model/budget.go b/core/model/budget.go new file mode 100644 index 0000000..e1798fa --- /dev/null +++ b/core/model/budget.go @@ -0,0 +1,58 @@ +package model + +import ( + "errors" + "github.com/openaccounting/oa-server/core/model/types" +) + +type BudgetInterface interface { + GetBudget(string, string) (*types.Budget, error) + CreateBudget(*types.Budget, string) error + DeleteBudget(string, string) error +} + +func (model *Model) GetBudget(orgId string, userId string) (*types.Budget, error) { + belongs, err := model.UserBelongsToOrg(userId, orgId) + + if err != nil { + return nil, err + } + + if belongs == false { + return nil, errors.New("User does not belong to org") + } + + return model.db.GetBudget(orgId) +} + +func (model *Model) CreateBudget(budget *types.Budget, userId string) error { + belongs, err := model.UserBelongsToOrg(userId, budget.OrgId) + + if err != nil { + return err + } + + if belongs == false { + return errors.New("User does not belong to org") + } + + if budget.OrgId == "" { + return errors.New("orgId required") + } + + return model.db.InsertAndReplaceBudget(budget) +} + +func (model *Model) DeleteBudget(orgId string, userId string) error { + belongs, err := model.UserBelongsToOrg(userId, orgId) + + if err != nil { + return err + } + + if belongs == false { + return errors.New("User does not belong to org") + } + + return model.db.DeleteBudget(orgId) +} diff --git a/core/model/db/budget.go b/core/model/db/budget.go new file mode 100644 index 0000000..af85f6c --- /dev/null +++ b/core/model/db/budget.go @@ -0,0 +1,117 @@ +package db + +import ( + "errors" + "github.com/openaccounting/oa-server/core/model/types" + "github.com/openaccounting/oa-server/core/util" + "time" +) + +type BudgetInterface interface { + GetBudget(string) (*types.Budget, error) + InsertAndReplaceBudget(*types.Budget) error + DeleteBudget(string) error +} + +const budgetFields = "LOWER(HEX(accountId)),inserted,amount" + +func (db *DB) GetBudget(orgId string) (*types.Budget, error) { + var budget types.Budget + var inserted int64 + + rows, err := db.Query("SELECT "+budgetFields+" FROM budgetitem WHERE orgId = UNHEX(?) ORDER BY HEX(accountId)", orgId) + + if err != nil { + return nil, err + } + + defer rows.Close() + + items := make([]*types.BudgetItem, 0) + + for rows.Next() { + i := new(types.BudgetItem) + err := rows.Scan(&i.AccountId, &inserted, &i.Amount) + if err != nil { + return nil, err + } + + items = append(items, i) + } + + err = rows.Err() + + if err != nil { + return nil, err + } + + if len(items) == 0 { + return nil, errors.New("Budget not found") + } + + budget.OrgId = orgId + budget.Inserted = util.MsToTime(inserted) + budget.Items = items + + return &budget, nil +} + +func (db *DB) InsertAndReplaceBudget(budget *types.Budget) (err error) { + budget.Inserted = time.Now() + + // Save to db + dbTx, err := db.Begin() + + if err != nil { + return + } + + defer func() { + if p := recover(); p != nil { + dbTx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + dbTx.Rollback() + } else { + err = dbTx.Commit() + } + }() + + // delete previous budget + query1 := "DELETE FROM budgetitem WHERE orgId = UNHEX(?)" + + _, err = dbTx.Exec( + query1, + budget.OrgId, + ) + + if err != nil { + return + } + + // save items + for _, item := range budget.Items { + query := "INSERT INTO budgetitem(orgId,accountId,inserted,amount) VALUES (UNHEX(?),UNHEX(?),?,?)" + + _, err = dbTx.Exec( + query, + budget.OrgId, + item.AccountId, + util.TimeToMs(budget.Inserted), + item.Amount) + + if err != nil { + return + } + } + + return +} + +func (db *DB) DeleteBudget(orgId string) error { + query := "DELETE FROM budgetitem WHERE orgId = UNHEX(?)" + + _, err := db.Exec(query, orgId) + + return err +} \ No newline at end of file diff --git a/core/model/db/db.go b/core/model/db/db.go index 168a413..5bf638a 100644 --- a/core/model/db/db.go +++ b/core/model/db/db.go @@ -19,6 +19,7 @@ type Datastore interface { SessionInterface ApiKeyInterface SystemHealthInteface + BudgetInterface } func NewDB(dataSourceName string) (*DB, error) { diff --git a/core/model/model.go b/core/model/model.go index b84ddbf..a053910 100644 --- a/core/model/model.go +++ b/core/model/model.go @@ -23,6 +23,7 @@ type Interface interface { SessionInterface ApiKeyInterface SystemHealthInteface + BudgetInterface } func NewModel(db db.Datastore, bcrypt util.Bcrypt, config types.Config) *Model { diff --git a/core/model/types/budget.go b/core/model/types/budget.go new file mode 100644 index 0000000..d8ac0b7 --- /dev/null +++ b/core/model/types/budget.go @@ -0,0 +1,17 @@ +package types + +import ( + "time" +) + +type Budget struct { + OrgId string `json:"orgId"` + Inserted time.Time `json:"inserted"` + Items []*BudgetItem `json:"items"` +} + +type BudgetItem struct { + OrgId string `json:"-"` + AccountId string `json:"accountId"` + Amount int64 `json:"amount"` +} diff --git a/indexes.sql b/indexes.sql index 7d93181..3efdcea 100644 --- a/indexes.sql +++ b/indexes.sql @@ -2,4 +2,5 @@ CREATE INDEX account_orgId_index ON account (orgId); CREATE INDEX split_accountId_index ON split (accountId); CREATE INDEX split_transactionId_index ON split (transactionId); CREATE INDEX split_date_index ON split (date); -CREATE INDEX split_updated_index ON split (updated); \ No newline at end of file +CREATE INDEX split_updated_index ON split (updated); +CREATE INDEX budgetitem_orgId_index ON budgetitem (orgId); \ No newline at end of file diff --git a/migrations/migrate3.go b/migrations/migrate3.go new file mode 100644 index 0000000..c7cf43a --- /dev/null +++ b/migrations/migrate3.go @@ -0,0 +1,105 @@ +package main + +import ( + "encoding/json" + "github.com/openaccounting/oa-server/core/model/db" + "github.com/openaccounting/oa-server/core/model/types" + "log" + "os" +) + +func main() { + if len(os.Args) != 2 { + log.Fatal("Usage: migrate3.go ") + } + + command := os.Args[1] + + if command != "upgrade" && command != "downgrade" { + log.Fatal("Usage: migrate3.go ") + } + + //filename is the path to the json config file + var config types.Config + file, err := os.Open("./config.json") + + if err != nil { + log.Fatal(err) + } + + decoder := json.NewDecoder(file) + err = decoder.Decode(&config) + + if err != nil { + log.Fatal(err) + } + + connectionString := config.User + ":" + config.Password + "@/" + config.Database + db, err := db.NewDB(connectionString) + + if command == "upgrade" { + err = upgrade(db) + } else { + err = downgrade(db) + } + + if err != nil { + log.Fatal(err) + } + + log.Println("done") +} + +func upgrade(db *db.DB) (err error) { + tx, err := db.Begin() + + if err != nil { + return + } + + defer func() { + if p := recover(); p != nil { + tx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + tx.Rollback() + } else { + err = tx.Commit() + } + }() + + query1 := "CREATE TABLE budgetitem (id INT UNSIGNED NOT NULL AUTO_INCREMENT, orgId BINARY(16) NOT NULL, accountId BINARY(16) NOT NULL, inserted BIGINT UNSIGNED NOT NULL, amount BIGINT NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;" + + if _, err = tx.Exec(query1); err != nil { + return + } + + return +} + +func downgrade(db *db.DB) (err error) { + tx, err := db.Begin() + + if err != nil { + return + } + + defer func() { + if p := recover(); p != nil { + tx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + tx.Rollback() + } else { + err = tx.Commit() + } + }() + + query1 := "DROP TABLE budgetitem" + + if _, err = tx.Exec(query1); err != nil { + return + } + + return +} diff --git a/schema.sql b/schema.sql index 36aa3a4..6db50e0 100644 --- a/schema.sql +++ b/schema.sql @@ -29,3 +29,5 @@ CREATE TABLE session (id BINARY(16) NOT NULL, inserted BIGINT UNSIGNED NOT NULL, CREATE TABLE apikey (id BINARY(16) NOT NULL, inserted BIGINT UNSIGNED NOT NULL, updated BIGINT UNSIGNED NOT NULL, userId BINARY(16) NOT NULL, label VARCHAR(300) NOT NULL, deleted BIGINT UNSIGNED, PRIMARY KEY(id)) ENGINE=InnoDB; CREATE TABLE invite (id VARCHAR(32) NOT NULL, orgId BINARY(16) NOT NULL, inserted BIGINT UNSIGNED NOT NULL, updated BIGINT UNSIGNED NOT NULL, email VARCHAR(100) NOT NULL, accepted BOOLEAN NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB; + +CREATE TABLE budgetitem (id INT UNSIGNED NOT NULL AUTO_INCREMENT, orgId BINARY(16) NOT NULL, accountId BINARY(16) NOT NULL, inserted BIGINT UNSIGNED NOT NULL, amount BIGINT NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB; \ No newline at end of file From 83f3cfc983f7801f741f98ee8d8cfa3aa4887294 Mon Sep 17 00:00:00 2001 From: Patrick Nagurny Date: Tue, 14 Jan 2020 14:22:15 -0500 Subject: [PATCH 2/3] api version 1.4.0 --- core/api/account.go | 20 ++++++++++---------- core/api/api.go | 2 +- core/api/apikey.go | 16 ++++++++-------- core/api/org.go | 32 ++++++++++++++++---------------- core/api/price.go | 12 ++++++------ core/api/session.go | 8 ++++---- core/api/syshealth.go | 4 ++-- core/api/transaction.go | 20 ++++++++++---------- core/api/user.go | 20 ++++++++++---------- core/api/version.go | 2 +- core/ws/ws.go | 2 +- 11 files changed, 69 insertions(+), 69 deletions(-) diff --git a/core/api/account.go b/core/api/account.go index 417de58..5ea4146 100644 --- a/core/api/account.go +++ b/core/api/account.go @@ -14,12 +14,12 @@ import ( /** * @api {get} /orgs/:orgId/accounts Get Accounts by Org id - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetOrgAccounts * @apiGroup Account * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccess {String} id Id of the Account. * @apiSuccess {String} orgId Id of the Org. @@ -86,12 +86,12 @@ func GetOrgAccounts(w rest.ResponseWriter, r *rest.Request) { /** * @api {get} /orgs/:orgId/accounts/:accountId Get Acount by Org id and Account id - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetOrgAccount * @apiGroup Account * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccess {String} id Id of the Account. * @apiSuccess {String} orgId Id of the Org. @@ -157,12 +157,12 @@ func GetOrgAccount(w rest.ResponseWriter, r *rest.Request) { /** * @api {post} /orgs/:orgId/accounts Create a new Account - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PostAccount * @apiGroup Account * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} id Id 32 character hex string * @apiParam {String} name Name of the Account. @@ -270,12 +270,12 @@ func PostAccounts(w rest.ResponseWriter, r *rest.Request, content []byte) { /** * @api {put} /orgs/:orgId/accounts/:accountId Modify an Account - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PutAccount * @apiGroup Account * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} id Id 32 character hex string * @apiParam {String} name Name of the Account. @@ -345,12 +345,12 @@ func PutAccount(w rest.ResponseWriter, r *rest.Request) { /** * @api {delete} /orgs/:orgId/accounts/:accountId Delete an Account - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName DeleteAccount * @apiGroup Account * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK diff --git a/core/api/api.go b/core/api/api.go index 6df338e..5ce9d9f 100644 --- a/core/api/api.go +++ b/core/api/api.go @@ -12,7 +12,7 @@ import ( * - add `POST /orgs/:orgId/budget` * - add `DELETE /orgs/:orgId/budget` * - * 1.3.0 + * 1.4.0 * - add org.timezone * * 1.2.0 diff --git a/core/api/apikey.go b/core/api/apikey.go index 5df5d83..7b4c608 100644 --- a/core/api/apikey.go +++ b/core/api/apikey.go @@ -9,12 +9,12 @@ import ( /** * @api {get} /apikeys Get API keys - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetApiKeys * @apiGroup ApiKey * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccess {String} id Id of the ApiKey. * @apiSuccess {Date} inserted Date ApiKey was created @@ -52,11 +52,11 @@ func GetApiKeys(w rest.ResponseWriter, r *rest.Request) { /** * @api {post} /apikeys Create a new API key - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PostApiKey * @apiGroup ApiKey * - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * @apiHeader {String} Authorization HTTP Basic Auth * * @apiParam {String} id 32 character hex string @@ -105,11 +105,11 @@ func PostApiKey(w rest.ResponseWriter, r *rest.Request) { /** * @api {put} /apikeys Modify an API key - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PutApiKey * @apiGroup ApiKey * - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * @apiHeader {String} Authorization HTTP Basic Auth * * @apiParam {String} id 32 character hex string @@ -160,12 +160,12 @@ func PutApiKey(w rest.ResponseWriter, r *rest.Request) { /** * @api {delete} /apikeys/:apiKeyId Delete an API key - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName DeleteApiKey * @apiGroup ApiKey * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK diff --git a/core/api/org.go b/core/api/org.go index d60aa17..75facc9 100644 --- a/core/api/org.go +++ b/core/api/org.go @@ -9,12 +9,12 @@ import ( /** * @api {get} /org/:orgId Get Org by id - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetOrg * @apiGroup Org * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccess {String} id Id of the Org. * @apiSuccess {Date} inserted Date Org was created @@ -55,12 +55,12 @@ func GetOrg(w rest.ResponseWriter, r *rest.Request) { /** * @api {get} /orgs Get a User's Orgs - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetOrgs * @apiGroup Org * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccess {String} id Id of the Org. * @apiSuccess {Date} inserted Date Org was created @@ -102,12 +102,12 @@ func GetOrgs(w rest.ResponseWriter, r *rest.Request) { /** * @api {post} /orgs Create a new Org - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PostOrg * @apiGroup Org * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} id Id 32 character hex string * @apiParam {String} name Name of the Org. @@ -159,12 +159,12 @@ func PostOrg(w rest.ResponseWriter, r *rest.Request) { /** * @api {put} /orgs/:orgId Modify an Org - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PutOrg * @apiGroup Org * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} name Name of the Org. * @@ -216,12 +216,12 @@ func PutOrg(w rest.ResponseWriter, r *rest.Request) { /** * @api {post} /orgs/:orgId/invites Invite a user to an Org - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PostInvite * @apiGroup Org * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} email Email address of user * @@ -272,12 +272,12 @@ func PostInvite(w rest.ResponseWriter, r *rest.Request) { /** * @api {put} /orgs/:orgId/invites/:inviteId Accept an invitation - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PutInvite * @apiGroup Org * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} accepted true * @@ -329,12 +329,12 @@ func PutInvite(w rest.ResponseWriter, r *rest.Request) { /** * @api {get} /orgs/:orgId/invites Get Org invites - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetInvites * @apiGroup Org * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccess {String} id Id of the Invite * @apiSuccess {orgId} id Id of the Org @@ -375,12 +375,12 @@ func GetInvites(w rest.ResponseWriter, r *rest.Request) { /** * @api {delete} /orgs/:orgId/invites/:inviteId Delete Invite - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName DeleteInvite * @apiGroup Org * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK diff --git a/core/api/price.go b/core/api/price.go index 08cd7f9..7d8cd21 100644 --- a/core/api/price.go +++ b/core/api/price.go @@ -11,12 +11,12 @@ import ( /** * @api {get} /org/:orgId/prices Get prices nearest in time or by currency - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetPrices * @apiGroup Price * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {Number} nearestDate Milliseconds since epoch * @apiParam {String} currency Currency code @@ -93,12 +93,12 @@ func GetPrices(w rest.ResponseWriter, r *rest.Request) { /** * @api {post} /orgs/:orgId/prices Create a new Price - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PostPrice * @apiGroup Price * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} id Id 32 character hex string. * @apiParam {String} orgId Id of the Org. @@ -155,12 +155,12 @@ func PostPrice(w rest.ResponseWriter, r *rest.Request) { /** * @api {delete} /orgs/:orgId/prices/:priceId Delete a Price - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName DeletePrice * @apiGroup Price * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK diff --git a/core/api/session.go b/core/api/session.go index 05741ff..f95e0d5 100644 --- a/core/api/session.go +++ b/core/api/session.go @@ -9,11 +9,11 @@ import ( /** * @api {post} /sessions Create a new Session - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PostSession * @apiGroup Session * - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * @apiHeader {String} Authorization HTTP Basic Auth * * @apiParam {String} id 32 character hex string @@ -59,12 +59,12 @@ func PostSession(w rest.ResponseWriter, r *rest.Request) { /** * @api {delete} /sessions/:sessionId Log out of a Session - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName DeleteSession * @apiGroup Session * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK diff --git a/core/api/syshealth.go b/core/api/syshealth.go index 2862ff1..01b7c5c 100644 --- a/core/api/syshealth.go +++ b/core/api/syshealth.go @@ -7,12 +7,12 @@ import ( /** * @api {get} /health-check Get system health status - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetSystemHealthStatus * @apiGroup SystemHealth * * - * @apiHeader {String} Accept-Version: 1.3.0 semver versioning + * @apiHeader {String} Accept-Version: 1.4.0 semver versioning * * @apiSuccess {String} database Database status: "ok"; "fail" * @apiSuccess {String} api API status: "ok" diff --git a/core/api/transaction.go b/core/api/transaction.go index a2a9965..1f9f18f 100644 --- a/core/api/transaction.go +++ b/core/api/transaction.go @@ -9,12 +9,12 @@ import ( /** * @api {get} /orgs/:orgId/accounts/:accountId/transactions Get Transactions by Account Id - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetAccountTransactions * @apiGroup Transaction * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccess {String} id Id of the Transaction. * @apiSuccess {String} orgId Id of the Org. @@ -85,12 +85,12 @@ func GetTransactionsByAccount(w rest.ResponseWriter, r *rest.Request) { /** * @api {get} /orgs/:orgId/transactions Get Transactions by Org Id - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetOrgTransactions * @apiGroup Transaction * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccess {String} id Id of the Transaction. * @apiSuccess {String} orgId Id of the Org. @@ -160,12 +160,12 @@ func GetTransactionsByOrg(w rest.ResponseWriter, r *rest.Request) { /** * @api {post} /orgs/:orgId/transactions Create a new Transaction - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PostTransaction * @apiGroup Transaction * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} id Id 32 character hex string * @apiParam {Date} date Date of the Transaction @@ -246,12 +246,12 @@ func PostTransaction(w rest.ResponseWriter, r *rest.Request) { /** * @api {put} /orgs/:orgId/transactions/:transactionId Modify a Transaction - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PutTransaction * @apiGroup Transaction * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} id 32 character hex string * @apiParam {Date} date Date of the Transaction @@ -333,12 +333,12 @@ func PutTransaction(w rest.ResponseWriter, r *rest.Request) { /** * @api {delete} /orgs/:orgId/transactions/:transactionId Delete a Transaction - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName DeleteTransaction * @apiGroup Transaction * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK diff --git a/core/api/user.go b/core/api/user.go index 3bc3f99..e8c1ff3 100644 --- a/core/api/user.go +++ b/core/api/user.go @@ -22,12 +22,12 @@ type ResetPasswordParams struct { /** * @api {get} /user Get Authenticated User - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName GetUser * @apiGroup User * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiSuccess {String} id Id of the User. * @apiSuccess {Date} inserted Date User was created @@ -64,11 +64,11 @@ func GetUser(w rest.ResponseWriter, r *rest.Request) { /** * @api {post} /users Create a new User - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PostUser * @apiGroup User * - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} id 32 character hex string * @apiParam {String} firstName First name of the User. @@ -123,12 +123,12 @@ func PostUser(w rest.ResponseWriter, r *rest.Request) { /** * @api {put} /user Modify User - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName PutUser * @apiGroup User * * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} password New password * @apiParam {String} code Password reset code. (Instead of Authorization header) @@ -204,11 +204,11 @@ func PutUser(w rest.ResponseWriter, r *rest.Request) { /** * @api {post} /user/verify Verify user email address - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName VerifyUser * @apiGroup User * - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} code Email verification code * @@ -238,11 +238,11 @@ func VerifyUser(w rest.ResponseWriter, r *rest.Request) { /** * @api {post} /user/reset-password Send reset password email - * @apiVersion 1.3.0 + * @apiVersion 1.4.0 * @apiName ResetPassword * @apiGroup User * - * @apiHeader {String} Accept-Version ^1.3.0 semver versioning + * @apiHeader {String} Accept-Version ^1.4.0 semver versioning * * @apiParam {String} email Email address for user * diff --git a/core/api/version.go b/core/api/version.go index 2b152d8..73a7c09 100644 --- a/core/api/version.go +++ b/core/api/version.go @@ -31,7 +31,7 @@ func (mw *VersionMiddleware) MiddlewareFunc(handler rest.HandlerFunc) rest.Handl rest.Error(writer, "Invalid version", http.StatusBadRequest) } - serverVersion, _ := semver.NewVersion("1.3.0") + serverVersion, _ := semver.NewVersion("1.4.0") // Pre-release versions compatVersion, _ := semver.NewVersion("0.1.8") diff --git a/core/ws/ws.go b/core/ws/ws.go index 6d3bd21..94ef369 100644 --- a/core/ws/ws.go +++ b/core/ws/ws.go @@ -14,7 +14,7 @@ import ( "sync" ) -const version = "1.3.0" +const version = "1.4.0" //var upgrader = websocket.Upgrader{} // use default options var txSubscriptions = make(map[string][]*websocket.Conn) From f2877230e289d0b14f2a6af0ff7cbb8150d19855 Mon Sep 17 00:00:00 2001 From: Patrick Nagurny Date: Tue, 14 Jan 2020 14:29:00 -0500 Subject: [PATCH 3/3] format code --- core/api/org.go | 66 ++++++++--------- core/auth/auth.go | 2 +- core/model/db/budget.go | 22 +++--- core/model/types/budget.go | 12 ++-- migrations/migrate1.go | 144 ++++++++++++++++++------------------- migrations/migrate2.go | 144 ++++++++++++++++++------------------- migrations/migrate3.go | 144 ++++++++++++++++++------------------- 7 files changed, 267 insertions(+), 267 deletions(-) diff --git a/core/api/org.go b/core/api/org.go index 75facc9..36cde51 100644 --- a/core/api/org.go +++ b/core/api/org.go @@ -54,39 +54,39 @@ func GetOrg(w rest.ResponseWriter, r *rest.Request) { } /** - * @api {get} /orgs Get a User's Orgs - * @apiVersion 1.4.0 - * @apiName GetOrgs - * @apiGroup Org - * - * @apiHeader {String} Authorization HTTP Basic Auth - * @apiHeader {String} Accept-Version ^1.4.0 semver versioning - * - * @apiSuccess {String} id Id of the Org. - * @apiSuccess {Date} inserted Date Org was created - * @apiSuccess {Date} updated Date Org was updated - * @apiSuccess {String} name Name of the Org. - * @apiSuccess {String} currency Three letter currency code. - * @apiSuccess {Number} precision How many digits the currency goes out to. - @apiSuccess {String} timezone Timezone to use for accounting. - * - * @apiSuccessExample Success-Response: - * HTTP/1.1 200 OK - * [ - * { - * "id": "11111111111111111111111111111111", - * "inserted": "2018-09-11T18:05:04.420Z", - * "updated": "2018-09-11T18:05:04.420Z", - * "name": "MyOrg", - * "currency": "USD", - * "precision": 2, - * "timezone": "America/New_York" - * } - * ] - * - * @apiUse NotAuthorizedError - * @apiUse InternalServerError - */ +* @api {get} /orgs Get a User's Orgs +* @apiVersion 1.4.0 +* @apiName GetOrgs +* @apiGroup Org +* +* @apiHeader {String} Authorization HTTP Basic Auth +* @apiHeader {String} Accept-Version ^1.4.0 semver versioning +* +* @apiSuccess {String} id Id of the Org. +* @apiSuccess {Date} inserted Date Org was created +* @apiSuccess {Date} updated Date Org was updated +* @apiSuccess {String} name Name of the Org. +* @apiSuccess {String} currency Three letter currency code. +* @apiSuccess {Number} precision How many digits the currency goes out to. +@apiSuccess {String} timezone Timezone to use for accounting. +* +* @apiSuccessExample Success-Response: +* HTTP/1.1 200 OK +* [ +* { +* "id": "11111111111111111111111111111111", +* "inserted": "2018-09-11T18:05:04.420Z", +* "updated": "2018-09-11T18:05:04.420Z", +* "name": "MyOrg", +* "currency": "USD", +* "precision": 2, +* "timezone": "America/New_York" +* } +* ] +* +* @apiUse NotAuthorizedError +* @apiUse InternalServerError +*/ func GetOrgs(w rest.ResponseWriter, r *rest.Request) { user := r.Env["USER"].(*types.User) diff --git a/core/auth/auth.go b/core/auth/auth.go index 4849a31..68a49a0 100644 --- a/core/auth/auth.go +++ b/core/auth/auth.go @@ -105,4 +105,4 @@ func (auth *AuthService) AuthenticateEmailVerifyCode(code string) (*types.User, } return u, nil -} \ No newline at end of file +} diff --git a/core/model/db/budget.go b/core/model/db/budget.go index af85f6c..e34cadc 100644 --- a/core/model/db/budget.go +++ b/core/model/db/budget.go @@ -77,17 +77,17 @@ func (db *DB) InsertAndReplaceBudget(budget *types.Budget) (err error) { } }() - // delete previous budget - query1 := "DELETE FROM budgetitem WHERE orgId = UNHEX(?)" + // delete previous budget + query1 := "DELETE FROM budgetitem WHERE orgId = UNHEX(?)" - _, err = dbTx.Exec( - query1, - budget.OrgId, - ) - - if err != nil { - return - } + _, err = dbTx.Exec( + query1, + budget.OrgId, + ) + + if err != nil { + return + } // save items for _, item := range budget.Items { @@ -114,4 +114,4 @@ func (db *DB) DeleteBudget(orgId string) error { _, err := db.Exec(query, orgId) return err -} \ No newline at end of file +} diff --git a/core/model/types/budget.go b/core/model/types/budget.go index d8ac0b7..398d09b 100644 --- a/core/model/types/budget.go +++ b/core/model/types/budget.go @@ -5,13 +5,13 @@ import ( ) type Budget struct { - OrgId string `json:"orgId"` - Inserted time.Time `json:"inserted"` - Items []*BudgetItem `json:"items"` + OrgId string `json:"orgId"` + Inserted time.Time `json:"inserted"` + Items []*BudgetItem `json:"items"` } type BudgetItem struct { - OrgId string `json:"-"` - AccountId string `json:"accountId"` - Amount int64 `json:"amount"` + OrgId string `json:"-"` + AccountId string `json:"accountId"` + Amount int64 `json:"amount"` } diff --git a/migrations/migrate1.go b/migrations/migrate1.go index a5be973..d5bd796 100644 --- a/migrations/migrate1.go +++ b/migrations/migrate1.go @@ -1,105 +1,105 @@ package main import ( - "encoding/json" - "github.com/openaccounting/oa-server/core/model/db" - "github.com/openaccounting/oa-server/core/model/types" - "log" - "os" + "encoding/json" + "github.com/openaccounting/oa-server/core/model/db" + "github.com/openaccounting/oa-server/core/model/types" + "log" + "os" ) func main() { - if len(os.Args) != 2 { - log.Fatal("Usage: migrate1.go ") - } + if len(os.Args) != 2 { + log.Fatal("Usage: migrate1.go ") + } - command := os.Args[1] + command := os.Args[1] - if command != "upgrade" && command != "downgrade" { - log.Fatal("Usage: migrate1.go ") - } + if command != "upgrade" && command != "downgrade" { + log.Fatal("Usage: migrate1.go ") + } - //filename is the path to the json config file - var config types.Config - file, err := os.Open("./config.json") + //filename is the path to the json config file + var config types.Config + file, err := os.Open("./config.json") - if err != nil { - log.Fatal(err) - } + if err != nil { + log.Fatal(err) + } - decoder := json.NewDecoder(file) - err = decoder.Decode(&config) + decoder := json.NewDecoder(file) + err = decoder.Decode(&config) - if err != nil { - log.Fatal(err) - } + if err != nil { + log.Fatal(err) + } - connectionString := config.User + ":" + config.Password + "@/" + config.Database - db, err := db.NewDB(connectionString) + connectionString := config.User + ":" + config.Password + "@/" + config.Database + db, err := db.NewDB(connectionString) - if command == "upgrade" { - err = upgrade(db) - } else { - err = downgrade(db) - } + if command == "upgrade" { + err = upgrade(db) + } else { + err = downgrade(db) + } - if err != nil { - log.Fatal(err) - } + if err != nil { + log.Fatal(err) + } - log.Println("done") + log.Println("done") } func upgrade(db *db.DB) (err error) { - tx, err := db.Begin() + tx, err := db.Begin() - if err != nil { - return - } + if err != nil { + return + } - defer func() { - if p := recover(); p != nil { - tx.Rollback() - panic(p) // re-throw panic after Rollback - } else if err != nil { - tx.Rollback() - } else { - err = tx.Commit() - } - }() + defer func() { + if p := recover(); p != nil { + tx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + tx.Rollback() + } else { + err = tx.Commit() + } + }() - query1 := "ALTER TABLE user ADD COLUMN signupSource VARCHAR(100) NOT NULL AFTER emailVerifyCode" + query1 := "ALTER TABLE user ADD COLUMN signupSource VARCHAR(100) NOT NULL AFTER emailVerifyCode" - if _, err = tx.Exec(query1); err != nil { - return - } + if _, err = tx.Exec(query1); err != nil { + return + } - return + return } func downgrade(db *db.DB) (err error) { - tx, err := db.Begin() + tx, err := db.Begin() - if err != nil { - return - } + if err != nil { + return + } - defer func() { - if p := recover(); p != nil { - tx.Rollback() - panic(p) // re-throw panic after Rollback - } else if err != nil { - tx.Rollback() - } else { - err = tx.Commit() - } - }() + defer func() { + if p := recover(); p != nil { + tx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + tx.Rollback() + } else { + err = tx.Commit() + } + }() - query1 := "ALTER TABLE user DROP COLUMN signupSource" + query1 := "ALTER TABLE user DROP COLUMN signupSource" - if _, err = tx.Exec(query1); err != nil { - return - } + if _, err = tx.Exec(query1); err != nil { + return + } - return + return } diff --git a/migrations/migrate2.go b/migrations/migrate2.go index 87f28d9..5a09364 100644 --- a/migrations/migrate2.go +++ b/migrations/migrate2.go @@ -1,105 +1,105 @@ package main import ( - "encoding/json" - "github.com/openaccounting/oa-server/core/model/db" - "github.com/openaccounting/oa-server/core/model/types" - "log" - "os" + "encoding/json" + "github.com/openaccounting/oa-server/core/model/db" + "github.com/openaccounting/oa-server/core/model/types" + "log" + "os" ) func main() { - if len(os.Args) != 2 { - log.Fatal("Usage: migrate2.go ") - } + if len(os.Args) != 2 { + log.Fatal("Usage: migrate2.go ") + } - command := os.Args[1] + command := os.Args[1] - if command != "upgrade" && command != "downgrade" { - log.Fatal("Usage: migrate2.go ") - } + if command != "upgrade" && command != "downgrade" { + log.Fatal("Usage: migrate2.go ") + } - //filename is the path to the json config file - var config types.Config - file, err := os.Open("./config.json") + //filename is the path to the json config file + var config types.Config + file, err := os.Open("./config.json") - if err != nil { - log.Fatal(err) - } + if err != nil { + log.Fatal(err) + } - decoder := json.NewDecoder(file) - err = decoder.Decode(&config) + decoder := json.NewDecoder(file) + err = decoder.Decode(&config) - if err != nil { - log.Fatal(err) - } + if err != nil { + log.Fatal(err) + } - connectionString := config.User + ":" + config.Password + "@/" + config.Database - db, err := db.NewDB(connectionString) + connectionString := config.User + ":" + config.Password + "@/" + config.Database + db, err := db.NewDB(connectionString) - if command == "upgrade" { - err = upgrade(db) - } else { - err = downgrade(db) - } + if command == "upgrade" { + err = upgrade(db) + } else { + err = downgrade(db) + } - if err != nil { - log.Fatal(err) - } + if err != nil { + log.Fatal(err) + } - log.Println("done") + log.Println("done") } func upgrade(db *db.DB) (err error) { - tx, err := db.Begin() + tx, err := db.Begin() - if err != nil { - return - } + if err != nil { + return + } - defer func() { - if p := recover(); p != nil { - tx.Rollback() - panic(p) // re-throw panic after Rollback - } else if err != nil { - tx.Rollback() - } else { - err = tx.Commit() - } - }() + defer func() { + if p := recover(); p != nil { + tx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + tx.Rollback() + } else { + err = tx.Commit() + } + }() - query1 := "ALTER TABLE org ADD COLUMN timezone VARCHAR(100) NOT NULL AFTER `precision`" + query1 := "ALTER TABLE org ADD COLUMN timezone VARCHAR(100) NOT NULL AFTER `precision`" - if _, err = tx.Exec(query1); err != nil { - return - } + if _, err = tx.Exec(query1); err != nil { + return + } - return + return } func downgrade(db *db.DB) (err error) { - tx, err := db.Begin() + tx, err := db.Begin() - if err != nil { - return - } + if err != nil { + return + } - defer func() { - if p := recover(); p != nil { - tx.Rollback() - panic(p) // re-throw panic after Rollback - } else if err != nil { - tx.Rollback() - } else { - err = tx.Commit() - } - }() + defer func() { + if p := recover(); p != nil { + tx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + tx.Rollback() + } else { + err = tx.Commit() + } + }() - query1 := "ALTER TABLE org DROP COLUMN timezone" + query1 := "ALTER TABLE org DROP COLUMN timezone" - if _, err = tx.Exec(query1); err != nil { - return - } + if _, err = tx.Exec(query1); err != nil { + return + } - return + return } diff --git a/migrations/migrate3.go b/migrations/migrate3.go index c7cf43a..608e1f9 100644 --- a/migrations/migrate3.go +++ b/migrations/migrate3.go @@ -1,105 +1,105 @@ package main import ( - "encoding/json" - "github.com/openaccounting/oa-server/core/model/db" - "github.com/openaccounting/oa-server/core/model/types" - "log" - "os" + "encoding/json" + "github.com/openaccounting/oa-server/core/model/db" + "github.com/openaccounting/oa-server/core/model/types" + "log" + "os" ) func main() { - if len(os.Args) != 2 { - log.Fatal("Usage: migrate3.go ") - } + if len(os.Args) != 2 { + log.Fatal("Usage: migrate3.go ") + } - command := os.Args[1] + command := os.Args[1] - if command != "upgrade" && command != "downgrade" { - log.Fatal("Usage: migrate3.go ") - } + if command != "upgrade" && command != "downgrade" { + log.Fatal("Usage: migrate3.go ") + } - //filename is the path to the json config file - var config types.Config - file, err := os.Open("./config.json") + //filename is the path to the json config file + var config types.Config + file, err := os.Open("./config.json") - if err != nil { - log.Fatal(err) - } + if err != nil { + log.Fatal(err) + } - decoder := json.NewDecoder(file) - err = decoder.Decode(&config) + decoder := json.NewDecoder(file) + err = decoder.Decode(&config) - if err != nil { - log.Fatal(err) - } + if err != nil { + log.Fatal(err) + } - connectionString := config.User + ":" + config.Password + "@/" + config.Database - db, err := db.NewDB(connectionString) + connectionString := config.User + ":" + config.Password + "@/" + config.Database + db, err := db.NewDB(connectionString) - if command == "upgrade" { - err = upgrade(db) - } else { - err = downgrade(db) - } + if command == "upgrade" { + err = upgrade(db) + } else { + err = downgrade(db) + } - if err != nil { - log.Fatal(err) - } + if err != nil { + log.Fatal(err) + } - log.Println("done") + log.Println("done") } func upgrade(db *db.DB) (err error) { - tx, err := db.Begin() + tx, err := db.Begin() - if err != nil { - return - } + if err != nil { + return + } - defer func() { - if p := recover(); p != nil { - tx.Rollback() - panic(p) // re-throw panic after Rollback - } else if err != nil { - tx.Rollback() - } else { - err = tx.Commit() - } - }() + defer func() { + if p := recover(); p != nil { + tx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + tx.Rollback() + } else { + err = tx.Commit() + } + }() - query1 := "CREATE TABLE budgetitem (id INT UNSIGNED NOT NULL AUTO_INCREMENT, orgId BINARY(16) NOT NULL, accountId BINARY(16) NOT NULL, inserted BIGINT UNSIGNED NOT NULL, amount BIGINT NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;" + query1 := "CREATE TABLE budgetitem (id INT UNSIGNED NOT NULL AUTO_INCREMENT, orgId BINARY(16) NOT NULL, accountId BINARY(16) NOT NULL, inserted BIGINT UNSIGNED NOT NULL, amount BIGINT NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;" - if _, err = tx.Exec(query1); err != nil { - return - } + if _, err = tx.Exec(query1); err != nil { + return + } - return + return } func downgrade(db *db.DB) (err error) { - tx, err := db.Begin() + tx, err := db.Begin() - if err != nil { - return - } + if err != nil { + return + } - defer func() { - if p := recover(); p != nil { - tx.Rollback() - panic(p) // re-throw panic after Rollback - } else if err != nil { - tx.Rollback() - } else { - err = tx.Commit() - } - }() + defer func() { + if p := recover(); p != nil { + tx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + tx.Rollback() + } else { + err = tx.Commit() + } + }() - query1 := "DROP TABLE budgetitem" + query1 := "DROP TABLE budgetitem" - if _, err = tx.Exec(query1); err != nil { - return - } + if _, err = tx.Exec(query1); err != nil { + return + } - return + return }