Skip to content

Commit

Permalink
more refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephanie You committed May 14, 2024
1 parent a93c3fa commit bd3e83a
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 131 deletions.
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ require (
github.com/Rhymond/go-money v1.0.12
github.com/mattn/go-sqlite3 v1.14.22
)

require (
github.com/DATA-DOG/go-sqlmock v1.5.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect
)

require gotest.tools/v3 v3.5.1
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw=
cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms=
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
github.com/Rhymond/go-money v1.0.12 h1:pl2YVxR1RljQRve1Uw3TG1CuBub7gTpfrXAdDhq19dw=
github.com/Rhymond/go-money v1.0.12/go.mod h1:iHvCuIvitxu2JIlAlhF0g9jHqjRSr+rpdOs7Omqlupg=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
26 changes: 2 additions & 24 deletions src/sage/cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,8 @@ type AddResponse struct {
Error error
}

// AddExpense adds an expense to the database
func AddExpense(addReq *AddRequest) *AddResponse {
err := verifyDatabase()
if err != nil {
return &AddResponse{
Success: false,
Error: fmt.Errorf("error verifying database: %w", err),
}
}

db, err := connectDB()
if err != nil {
return &AddResponse{
Success: false,
Error: fmt.Errorf("error connecting to database: %w", err),
}
}
defer db.Close()

return addExec(db, addReq)
}

// addExec adds an expense to the database
func addExec(db *sql.DB, req *AddRequest) *AddResponse {
// addExpense adds an expense to the database
func AddExpense(db *sql.DB, req *AddRequest) *AddResponse {
_, err := db.Exec(fmt.Sprintf("INSERT INTO expenses (date_spent, location, description, amt) VALUES ('%s', '%s', '%s', %f)",
req.Expense.Date.String(),
req.Expense.Location,
Expand Down
68 changes: 39 additions & 29 deletions src/sage/cmd/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,44 @@ import (
"os"
)

var createTableQuery string = `CREATE TABLE IF NOT EXISTS expenses (
id INTEGER PRIMARY KEY,
date_spent DATE NOT NULL,
location VARCHAR(255),
description VARCHAR(255),
amt DECIMAL(19,4) NOT NULL
)`

// verifyDatabase checks if the sage folder and sage.db database exists. Creates the necessary folder and SQLite file
const (
CREATE_TABLE_QUERY string = `CREATE TABLE IF NOT EXISTS expenses (
id INTEGER PRIMARY KEY,
date_spent DATE NOT NULL,
location VARCHAR(255),
description VARCHAR(255),
amt DECIMAL(19,4) NOT NULL
)`
SAGE_DB_NAME string = "sage.db"
)

// ConnectDB connects to the given database, or creates it if it doesn't exist. Also initializes the `expenses` table
// if it doesn't exist.
func ConnectDB(db_name string) (*sql.DB, error) {
// Verify database
err := verifyDatabase(db_name)
if err != nil {
return nil, errors.New("error verifying database: " + err.Error())
}

// Connect to database
db, err := sql.Open("sqlite3", db_name)
if err != nil {
return nil, errors.New("error connecting to database: " + err.Error())
}

// create `expenses` table if it doesn't exist
_, err = db.Exec(CREATE_TABLE_QUERY)
if err != nil {
return nil, errors.New("error initializing 'expenses' table: " + err.Error())
}

return db, nil
}

// verifyDatabase checks if the sage folder and given database exists. Creates the necessary folder and SQLite file
// if it doesn't.
func verifyDatabase() error {
func verifyDatabase(db_name string) error {
dirname, err := os.UserHomeDir()
if err != nil {
return errors.New("error getting user home directory: " + err.Error())
Expand All @@ -30,8 +57,8 @@ func verifyDatabase() error {
}
}

if _, err := os.Stat(dirname + "/sage/sage.db"); errors.Is(err, fs.ErrNotExist) {
file, err := os.Create(dirname + "/sage/sage.db")
if _, err := os.Stat(dirname + "/sage/" + db_name); errors.Is(err, fs.ErrNotExist) {
file, err := os.Create(dirname + "/sage/" + db_name)
if err != nil {
return errors.New("error creating database file: " + err.Error())
}
Expand All @@ -40,20 +67,3 @@ func verifyDatabase() error {

return nil
}

// connectDB connects to the SQLite database and initializes the `expenses` table if it doesn't exist.
func connectDB() (*sql.DB, error) {
// Connect to database
db, err := sql.Open("sqlite3", "sage.db")
if err != nil {
return nil, errors.New("error connecting to database: " + err.Error())
}

// create `expenses` table if it doesn't exist
_, err = db.Exec(createTableQuery)
if err != nil {
return nil, errors.New("error initializing 'expenses' table: " + err.Error())
}

return db, nil
}
23 changes: 1 addition & 22 deletions src/sage/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,7 @@ type DeleteResponse struct {
}

// DeleteExpense removes an expense from the database
func DeleteExpense(delReq *DeleteRequest) *DeleteResponse {
err := verifyDatabase()
if err != nil {
return &DeleteResponse{
Success: false,
Error: fmt.Errorf("error verifying database: %w", err),
}
}

db, err := connectDB()
if err != nil {
return &DeleteResponse{
Success: false,
Error: fmt.Errorf("error connecting to database: %w", err),
}
}
defer db.Close()

return deleteExec(db, delReq)
}

func deleteExec(db *sql.DB, req *DeleteRequest) *DeleteResponse {
func DeleteExpense(db *sql.DB, req *DeleteRequest) *DeleteResponse {
_, err := db.Exec(fmt.Sprintf("DELETE FROM expenses WHERE id = '%d'", req.Id))
if err != nil {
return &DeleteResponse{
Expand Down
25 changes: 2 additions & 23 deletions src/sage/cmd/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,9 @@ type LogResponse struct {
Result *sql.Rows
}

// LogExpenses retrieves the list of expenses corresponding to the given options and displays the date, location,
// LogExpenses retrieves the list of expenses corresponding to the given options and returns the date, location,
// description, and amount (and optionally the expense ID)
func LogExpenses(logReq *LogRequest) *LogResponse {
err := verifyDatabase()
if err != nil {
return &LogResponse{
Success: false,
Error: fmt.Errorf("error verifying database: %w", err),
}
}

db, err := connectDB()
if err != nil {
return &LogResponse{
Success: false,
Error: fmt.Errorf("error connecting to database: %w", err),
}
}
defer db.Close()

return logExec(db, logReq)
}

func logExec(db *sql.DB, req *LogRequest) *LogResponse {
func LogExpenses(db *sql.DB, req *LogRequest) *LogResponse {
connector := "WHERE"
var sb strings.Builder
sb.WriteString("SELECT ")
Expand Down
25 changes: 2 additions & 23 deletions src/sage/cmd/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,8 @@ type SummaryResponse struct {
Result *sql.Rows
}

// Prints the sum of expenses each month
func SummarizeExpenses(sumReq *SummaryRequest) *SummaryResponse {
err := verifyDatabase()
if err != nil {
return &SummaryResponse{
Success: false,
Error: fmt.Errorf("error verifying database: %w", err),
}
}

db, err := connectDB()
if err != nil {
return &SummaryResponse{
Success: false,
Error: fmt.Errorf("error connecting to database: %w", err),
}
}
defer db.Close()

return summaryExec(db, sumReq)
}

func summaryExec(db *sql.DB, req *SummaryRequest) *SummaryResponse {
// SummarizeExpenses retrieves the sum of expenses each month
func SummarizeExpenses(db *sql.DB, req *SummaryRequest) *SummaryResponse {
connector := "WHERE"
var sb strings.Builder
sb.WriteString("SELECT strftime('%Y-%m', date_spent) AS month, sum(amt) AS total_spent FROM expenses")
Expand Down
41 changes: 31 additions & 10 deletions src/sage/controller/CLIController.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ func RunCLIController() int {
return 1
}

addResp := cmd.AddExpense(addReq)
db, err := cmd.ConnectDB("sage.db")
if err != nil {
log.Println("error connecting to database: ", err)
return 1
}
addResp := cmd.AddExpense(db, addReq)
if addResp.Success {
fmt.Println("Expense added successfully")
} else {
Expand All @@ -59,15 +64,20 @@ func RunCLIController() int {
}
}

logResp := cmd.LogExpenses(logReq)
db, err := cmd.ConnectDB("sage.db")
if err != nil {
log.Println("error connecting to database: ", err)
return 1
}
logResp := cmd.LogExpenses(db, logReq)
if logResp.Success {
defer logResp.Result.Close()

var date time.Time
var location string
var description string
var amt float64
for logResp.Result.Next() {
var date time.Time
var location string
var description string
var amt float64
if logResp.ShowId {
var id int
err := logResp.Result.Scan(&id, &date, &location, &description, &amt)
Expand Down Expand Up @@ -99,13 +109,18 @@ func RunCLIController() int {
}
}

sumResp := cmd.SummarizeExpenses(sumReq)
db, err := cmd.ConnectDB("sage.db")
if err != nil {
log.Println("error connecting to database: ", err)
return 1
}
sumResp := cmd.SummarizeExpenses(db, sumReq)
if sumResp.Success {
defer sumResp.Result.Close()

var month string
var totalSpent float64
for sumResp.Result.Next() {
var month string
var totalSpent float64
err = sumResp.Result.Scan(&month, &totalSpent)
if err != nil {
log.Println("error reading calculated summary: " + err.Error())
Expand All @@ -131,7 +146,13 @@ func RunCLIController() int {
log.Println("invalid ID provided: ", err)
return 1
}
deleteResp := cmd.DeleteExpense(&cmd.DeleteRequest{

db, err := cmd.ConnectDB("sage.db")
if err != nil {
log.Println("error connecting to database: ", err)
return 1
}
deleteResp := cmd.DeleteExpense(db, &cmd.DeleteRequest{
Id: id,
})
if deleteResp.Success {
Expand Down

0 comments on commit bd3e83a

Please sign in to comment.