Skip to content

Commit

Permalink
test: add database tests (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhth committed Aug 24, 2024
1 parent 1195f43 commit 40db552
Show file tree
Hide file tree
Showing 14 changed files with 493 additions and 264 deletions.
13 changes: 1 addition & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@ env:

jobs:
build:
name: build
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
Expand All @@ -32,10 +28,3 @@ jobs:
run: go build -v ./...
- name: go test
run: go test -v ./...
- name: run omm
run: |
go build .
cat assets/sample-tasks.txt | ./omm import
./omm 'test: a task'
./omm tasks
./.github/scripts/checknumtasks.sh "$(./omm tasks | wc -l | xargs)" 11
37 changes: 37 additions & 0 deletions .github/workflows/run.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: run

on:
push:
branches: [ "main" ]
pull_request:
paths:
- "go.*"
- "**/*.go"
- ".github/workflows/*.yml"

permissions:
contents: read

env:
GO_VERSION: '1.22.5'

jobs:
run:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: build
run: go build .
- name: run
run: |
cat assets/sample-tasks.txt | ./omm import
./omm 'test: a task'
./omm tasks
./.github/scripts/checknumtasks.sh "$(./omm tasks | wc -l | xargs)" 11
34 changes: 0 additions & 34 deletions cmd/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package cmd

import (
"database/sql"
"time"
)

func getDB(dbpath string) (*sql.DB, error) {
Expand All @@ -14,36 +13,3 @@ func getDB(dbpath string) (*sql.DB, error) {
db.SetMaxIdleConns(1)
return db, err
}

func initDB(db *sql.DB) error {
// these init queries cannot be changed once omm is released; only further
// migrations can be added, which are run when omm sees a difference between
// the values in the db_versions table and latestDBVersion
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS db_versions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
version INTEGER NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS task (
id INTEGER PRIMARY KEY AUTOINCREMENT,
summary TEXT NOT NULL,
active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE task_sequence (
id INTEGER PRIMARY KEY,
sequence JSON NOT NULL
);
INSERT INTO task_sequence (id, sequence) VALUES (1, '[]');
INSERT INTO db_versions (version, created_at)
VALUES (1, ?);
`, time.Now().UTC())

return err
}
2 changes: 1 addition & 1 deletion cmd/guide.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func insertGuideTasks(db *sql.DB) error {
}
}

err = pers.InsertTasksIntoDB(db, tasks)
_, err = pers.InsertTasks(db, tasks, true)

return err
}
26 changes: 22 additions & 4 deletions cmd/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import (
"time"

pers "github.com/dhth/omm/internal/persistence"
"github.com/dhth/omm/internal/types"
)

var errWillExceedCapacity = errors.New("import will exceed capacity")

func importTask(db *sql.DB, taskSummary string) error {
numTasks, err := pers.FetchNumActiveTasksFromDB(db)
numTasks, err := pers.FetchNumActiveTasksShown(db)
if err != nil {
return err
}
Expand All @@ -21,11 +22,18 @@ func importTask(db *sql.DB, taskSummary string) error {
}

now := time.Now()
return pers.ImportTaskIntoDB(db, taskSummary, true, now, now)
task := types.Task{
Summary: taskSummary,
Active: true,
CreatedAt: now,
UpdatedAt: now,
}
_, err = pers.InsertTasks(db, []types.Task{task}, true)
return err
}

func importTasks(db *sql.DB, taskSummaries []string) error {
numTasks, err := pers.FetchNumActiveTasksFromDB(db)
numTasks, err := pers.FetchNumActiveTasksShown(db)
if err != nil {
return err
}
Expand All @@ -34,5 +42,15 @@ func importTasks(db *sql.DB, taskSummaries []string) error {
}

now := time.Now()
return pers.ImportTaskSummariesIntoDB(db, taskSummaries, true, now, now)
tasks := make([]types.Task, len(taskSummaries))
for i, summ := range taskSummaries {
tasks[i] = types.Task{
Summary: summ,
Active: true,
CreatedAt: now,
UpdatedAt: now,
}
}
_, err = pers.InsertTasks(db, tasks, true)
return err
}
59 changes: 29 additions & 30 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,23 @@ const (
)

var (
errConfigFileExtIncorrect = errors.New("config file must be a TOML file")
errConfigFileDoesntExist = errors.New("config file does not exist")
errDBFileExtIncorrect = errors.New("db file needs to end with .db")

errMaxImportLimitExceeded = errors.New("import limit exceeded")
errNothingToImport = errors.New("nothing to import")

errListDensityIncorrect = errors.New("list density is incorrect; valid values: compact/spacious")

errCouldntGetHomeDir = errors.New("couldn't get home directory")
errConfigFileExtIncorrect = errors.New("config file must be a TOML file")
errConfigFileDoesntExist = errors.New("config file does not exist")
errDBFileExtIncorrect = errors.New("db file needs to end with .db")
errMaxImportLimitExceeded = errors.New("import limit exceeded")
errNothingToImport = errors.New("nothing to import")
errListDensityIncorrect = errors.New("list density is incorrect; valid values: compact/spacious")
errCouldntCreateDBDirectory = errors.New("couldn't create directory for database")
errCouldntCreateDB = errors.New("couldn't create database")
errCouldntInitializeDB = errors.New("couldn't initialize database")
errCouldntOpenDB = errors.New("couldn't open database")
errCouldntSetupGuide = errors.New("couldn't set up guided walkthrough")

//go:embed assets/updates.txt
updateContents string

reportIssueMsg = fmt.Sprintf("Let %s know about this error via %s.", author, repoIssuesURL)
reportIssueMsg = fmt.Sprintf("This isn't supposed to happen; let %s know about this error via \n%s.", author, repoIssuesURL)
maxImportNumMsg = fmt.Sprintf(`A maximum of %d tasks that can be imported at a time.
Archive/Delete tasks that are not active using ctrl+d/ctrl+x.
Expand All @@ -68,14 +67,22 @@ Archive/Delete tasks that are not active using ctrl+d/ctrl+x.

func Execute(version string) error {
rootCmd, err := NewRootCommand()

rootCmd.Version = version
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
switch {
case errors.Is(err, errCouldntGetHomeDir):
fmt.Printf("\n%s\n", reportIssueMsg)
}
return err
}
rootCmd.Version = version

return rootCmd.Execute()
err = rootCmd.Execute()
switch {
case errors.Is(err, errCouldntSetupGuide):
fmt.Printf("\n%s\n", reportIssueMsg)
}
return err
}

func setupDB(dbPathFull string) (*sql.DB, error) {
Expand All @@ -96,11 +103,11 @@ func setupDB(dbPathFull string) (*sql.DB, error) {
return nil, fmt.Errorf("%w: %s", errCouldntCreateDB, err.Error())
}

err = initDB(db)
err = pers.InitDB(db)
if err != nil {
return nil, fmt.Errorf("%w: %s", errCouldntInitializeDB, err.Error())
}
err = upgradeDB(db, 1)
err = pers.UpgradeDB(db, 1)
if err != nil {
return nil, err
}
Expand All @@ -109,7 +116,7 @@ func setupDB(dbPathFull string) (*sql.DB, error) {
if err != nil {
return nil, fmt.Errorf("%w: %s", errCouldntOpenDB, err.Error())
}
err = upgradeDBIfNeeded(db)
err = pers.UpgradeDBIfNeeded(db)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -213,19 +220,19 @@ Clean up error: %s
%s
`, reportIssueMsg)
case errors.Is(err, errCouldntFetchDBVersion):
case errors.Is(err, pers.ErrCouldntFetchDBVersion):
fmt.Fprintf(os.Stderr, `Couldn't get omm's latest database version. This is a fatal error.
%s
`, reportIssueMsg)
case errors.Is(err, errDBDowngraded):
case errors.Is(err, pers.ErrDBDowngraded):
fmt.Fprintf(os.Stderr, `Looks like you downgraded omm. You should either delete omm's database file (you
will lose data by doing that), or upgrade omm to the latest version.
%s
`, reportIssueMsg)
case errors.Is(err, errDBMigrationFailed):
case errors.Is(err, pers.ErrDBMigrationFailed):
fmt.Fprintf(os.Stderr, `Something went wrong migrating omm's database. This is not supposed to happen.
You can try running omm by passing it a custom database file path (using
--db-path; this will create a new database) to see if that fixes things. If that
Expand Down Expand Up @@ -360,10 +367,7 @@ Sorry for breaking the upgrade step!
PreRunE: func(_ *cobra.Command, _ []string) error {
guideErr := insertGuideTasks(db)
if guideErr != nil {
return fmt.Errorf(`Failed to set up a guided walkthrough.
%s
Error: %w`, reportIssueMsg, guideErr)
return fmt.Errorf("%w: %s", errCouldntSetupGuide, guideErr.Error())
}

return nil
Expand Down Expand Up @@ -405,12 +409,7 @@ Error: %w`, reportIssueMsg, guideErr)
var configPathAdditionalCxt, dbPathAdditionalCxt string
hd, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf(`Couldn't get your home directory. This is a fatal error;
use --dbpath to specify database path manually
%s
Error: %w`, reportIssueMsg, err)
return nil, fmt.Errorf("%w: %s", errCouldntGetHomeDir, err.Error())
}

switch ros {
Expand Down
2 changes: 1 addition & 1 deletion cmd/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func printTasks(db *sql.DB, limit uint8, writer io.Writer) error {
tasks, err := pers.FetchActiveTasksFromDB(db, int(limit))
tasks, err := pers.FetchActiveTasks(db, int(limit))
if err != nil {
return err
}
Expand Down
39 changes: 39 additions & 0 deletions internal/persistence/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package persistence

import (
"database/sql"
"time"
)

func InitDB(db *sql.DB) error {
// these init queries cannot be changed once omm is released; only further
// migrations can be added, which are run when omm sees a difference between
// the values in the db_versions table and latestDBVersion
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS db_versions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
version INTEGER NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS task (
id INTEGER PRIMARY KEY AUTOINCREMENT,
summary TEXT NOT NULL,
active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE task_sequence (
id INTEGER PRIMARY KEY,
sequence JSON NOT NULL
);
INSERT INTO task_sequence (id, sequence) VALUES (1, '[]');
INSERT INTO db_versions (version, created_at)
VALUES (1, ?);
`, time.Now().UTC())

return err
}
Loading

0 comments on commit 40db552

Please sign in to comment.