Skip to content

Commit

Permalink
Replace the current store from file system to sqlite
Browse files Browse the repository at this point in the history
  • Loading branch information
claudealdric committed Sep 28, 2024
1 parent 04f739e commit 4d24658
Show file tree
Hide file tree
Showing 12 changed files with 338 additions and 25 deletions.
2 changes: 1 addition & 1 deletion api/get_task_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestHandleGetTaskById(t *testing.T) {
assert.Calls(t, data.GetTaskByIdCalls, 1)
assert.Equals(
t,
testutils.GetTaskFromResponse(t, response.Body),
*testutils.GetTaskFromResponse(t, response.Body),
wantedTask,
)
})
Expand Down
4 changes: 2 additions & 2 deletions api/patch_task_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestHandlePatchTask(t *testing.T) {
assert.Calls(t, data.UpdateTaskCalls, 1)
assert.Equals(
t,
testutils.GetTaskFromResponse(t, response.Body),
*testutils.GetTaskFromResponse(t, response.Body),
models.Task{Id: task.Id, Title: newTitle},
)
})
Expand Down Expand Up @@ -162,7 +162,7 @@ func TestHandlePatchTask(t *testing.T) {
assert.Calls(t, data.UpdateTaskCalls, 1)
assert.Equals(
t,
testutils.GetTaskFromResponse(t, response.Body),
*testutils.GetTaskFromResponse(t, response.Body),
models.Task{Id: taskToUpdate.Id, Title: newTitle},
)

Expand Down
2 changes: 1 addition & 1 deletion api/post_task_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestHandlePostTask(t *testing.T) {
assert.Equals(
t,
testutils.GetTaskFromResponse(t, response.Body),
*newTask,
newTask,
)
})

Expand Down
Empty file added data.db
Empty file.
Binary file added data/data.db
Binary file not shown.
70 changes: 70 additions & 0 deletions data/init_db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package data

import (
"database/sql"
"log"
)

func InitDb(db *sql.DB) {
createUsersTable(db)
seedUsersTable(db)
createTasksTable(db)
seedTasksTable(db)
}

func createTasksTable(db *sql.DB) {
_, err := db.Exec(`
create table tasks (
id integer primary key autoincrement,
title text not null
)
`)
if err != nil {
log.Fatalln("failed creating the tasks table:", err)
}
}

func createUsersTable(db *sql.DB) {
_, err := db.Exec(`
create table users (
id integer primary key autoincrement,
name text not null,
email text not null unique,
password text not null
)
`)
if err != nil {
log.Fatalln("failed creating the users table:", err)
}
}

func seedUsersTable(db *sql.DB) {
_, err := db.Exec(`
insert into users (name, email, password)
values
('Claude Aldric', '[email protected]', 'Caput Draconis')
`)
if err != nil {
log.Fatalln("failed seeding the users table:", err)
}

_, err = db.Exec(`
insert into users (name, email, password)
values
('John Doe', '[email protected]', 'password')
`)
if err != nil {
log.Fatalln("failed seeding the users table:", err)
}
}

func seedTasksTable(db *sql.DB) {
_, err := db.Exec(`
insert into tasks (title)
values
('This is the first task')
`)
if err != nil {
log.Fatalln("failed seeding the users table:", err)
}
}
147 changes: 147 additions & 0 deletions data/sqlite_store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package data

import (
"database/sql"

"github.com/claudealdric/go-todolist-restful-api-server/models"
"golang.org/x/crypto/bcrypt"
)

type SqliteStore struct {
db *sql.DB
}

func NewSqliteStore(db *sql.DB) *SqliteStore {
s := SqliteStore{db}
return &s
}

func (s *SqliteStore) CreateTask(dto *models.CreateTaskDTO) (*models.Task, error) {
result, err := s.db.Exec(`
insert into tasks (title)
values
(?)
`, dto.Title)
if err != nil {
return nil, err
}

taskId, err := result.LastInsertId()
if err != nil {
return nil, err
}

return models.NewTask(int(taskId), dto.Title), nil
}

func (s *SqliteStore) CreateUser(dto *models.CreateUserDTO) (*models.User, error) {
hashedPassword, err := bcrypt.GenerateFromPassword(
[]byte(dto.Password),
bcrypt.DefaultCost,
)
if err != nil {
return nil, err
}

result, err := s.db.Exec(`
insert into users (name, email, password)
values
(?, ?, ?)
`, dto.Name, dto.Email, hashedPassword)
if err != nil {
return nil, err
}

userId, err := result.LastInsertId()
if err != nil {
return nil, err
}

return models.NewUser(int(userId), dto.Name, dto.Email, dto.Password), nil
}

func (s *SqliteStore) DeleteTaskById(id int) error {
_, err := s.db.Exec(`
delete from tasks where id = ?
`, id)
return err
}

func (s *SqliteStore) GetTaskById(id int) (*models.Task, error) {
var task models.Task
err := s.db.QueryRow(`select * from tasks where id = ?`, id).Scan(
&task.Id,
&task.Title,
)
if err != nil {
return nil, err
}
return &task, nil
}

func (s *SqliteStore) GetTasks() ([]models.Task, error) {
rows, err := s.db.Query(`select * from tasks`)
if err != nil {
return nil, err
}
defer rows.Close()
var tasks []models.Task
for rows.Next() {
var task models.Task
err := rows.Scan(&task.Id, &task.Title)
if err != nil {
return nil, err
}
tasks = append(tasks, task)
}
return tasks, nil
}

func (s *SqliteStore) GetUsers() ([]models.User, error) {
rows, err := s.db.Query(`select * from users`)
if err != nil {
return nil, err
}
defer rows.Close()
var users []models.User
for rows.Next() {
var user models.User
err := rows.Scan(&user.Id, &user.Name, &user.Email, &user.Password)
if err != nil {
return nil, err
}
users = append(users, user)
}
return users, nil
}

func (s *SqliteStore) GetUserByEmail(email string) (*models.User, error) {
var user models.User
err := s.db.QueryRow(`select * from users where email = ?`, email).Scan(
&user.Id,
&user.Name,
&user.Email,
&user.Password,
)
if err != nil {
return nil, err
}
return &user, nil
}

func (s *SqliteStore) UpdateTask(task *models.Task) (*models.Task, error) {
_, err := s.db.Exec(`
update tasks
set title = ?
where id = ?
`, task.Title, task.Id)
if err != nil {
return nil, err
}
updatedTask, err := s.GetTaskById(task.Id)
if err != nil {
return nil, err
}

return updatedTask, nil
}
21 changes: 11 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
package main

import (
"database/sql"
"fmt"
"log"
"net/http"
"os"
"path/filepath"

_ "github.com/mattn/go-sqlite3"

"github.com/claudealdric/go-todolist-restful-api-server/api"
"github.com/claudealdric/go-todolist-restful-api-server/data"
)

const port = 8080
const dbDirName = "tmp"
const dbFileName = "db.json"

func main() {
if err := os.MkdirAll(dbDirName, os.ModePerm); err != nil {
log.Fatalf("failed to create directory: %v", err)
}
dbPath := filepath.Join(dbDirName, dbFileName)
dbFile, err := os.OpenFile(dbPath, os.O_RDWR|os.O_CREATE, 0666)
os.Remove("./data/data.db")
db, err := sql.Open("sqlite3", "./data/data.db")
if err != nil {
log.Fatalf("problem opening %s %v", dbFileName, err)
log.Fatal(err)
}
store, err := data.NewFileSystemStore(dbFile)
defer db.Close()

data.InitDb(db)

store := data.NewSqliteStore(db)
if err != nil {
log.Fatalf("problem creating file system data store: %v", err)
}
Expand Down
Loading

0 comments on commit 4d24658

Please sign in to comment.