Rename to craban

This commit is contained in:
Miguel de la Cruz 2021-09-12 18:57:42 +02:00
parent 38767a78d3
commit ca0bfa2398
217 changed files with 23 additions and 23 deletions

View file

@ -0,0 +1,80 @@
package store
import (
"database/sql"
"fmt"
"strings"
_ "github.com/mattn/go-sqlite3"
)
type Store struct {
Path string
Conn *sql.DB
userStore *UserStore
}
func addPathOptions(path string) string {
if !strings.HasPrefix(path, ":memory:") {
path = "file:" + path
}
return fmt.Sprintf("%s?_foreign_keys=true", path)
}
func NewStore(path string) (*Store, error) {
s := &Store{Path: path}
// ToDo: should do this at start time instead of create time?
conn, err := sql.Open("sqlite3", addPathOptions(path))
if err != nil {
return nil, err
}
s.Conn = conn
if err := s.EnsureSchema(); err != nil {
return nil, err
}
// init stores
s.userStore = NewUserStore(s)
return s, nil
}
func (s *Store) Close() error {
return s.Conn.Close()
}
func (s *Store) User() *UserStore {
return s.userStore
}
func (s *Store) EnsureSchema() error {
schema := `
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(255) NOT NULL,
mail VARCHAR(255) UNIQUE NOT NULL,
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL
);
CREATE TABLE IF NOT EXISTS game (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
name VARCHAR(255) NOT NULL
);
CREATE TABLE IF NOT EXISTS gamemember (
game_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
role VARCHAR(255) NOT NULL,
PRIMARY KEY (game_id, user_id)
);
`
_, err := s.Conn.Exec(schema)
return err
}

View file

@ -0,0 +1,32 @@
package store
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestAddPathOptions(t *testing.T) {
testCases := []struct {
Name string
Path string
Expected string
}{
{
Name: "Path is memory",
Path: ":memory:",
Expected: ":memory:?_foreign_keys=true",
},
{
Name: "Path is a file path",
Path: "./some_file.sqlite",
Expected: "file:./some_file.sqlite?_foreign_keys=true",
},
}
for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
require.Equal(t, tc.Expected, addPathOptions(tc.Path))
})
}
}

View file

@ -0,0 +1,40 @@
package store
import (
"testing"
"git.ctrlz.es/mgdelacroix/craban/model"
"github.com/icrowley/fake"
"github.com/stretchr/testify/require"
)
type TestHelper struct {
t *testing.T
store *Store
}
func NewTestHelper(t *testing.T) (*TestHelper, func()) {
s, err := NewStore(":memory:")
require.NoError(t, err)
teardown := func() {
require.NoError(t, s.Close())
}
return &TestHelper{t: t, store: s}, teardown
}
func (th *TestHelper) NewUser() *model.User {
user := &model.User{
Name: fake.FullName(),
Mail: fake.EmailAddress(),
Username: fake.UserName(),
Password: fake.SimplePassword(),
}
newUser, err := th.store.User().Create(user)
require.NoError(th.t, err)
return newUser
}

View file

@ -0,0 +1,87 @@
package store
import (
"database/sql"
sq "github.com/Masterminds/squirrel"
"git.ctrlz.es/mgdelacroix/craban/model"
)
var userColumns = []string{"id", "name", "mail", "username", "password"}
type UserStore struct {
Conn *sql.DB
}
func NewUserStore(s *Store) *UserStore {
return &UserStore{Conn: s.Conn}
}
func (us *UserStore) Q() sq.StatementBuilderType {
return sq.StatementBuilder.RunWith(us.Conn)
}
func (us *UserStore) usersFromRows(rows *sql.Rows) ([]*model.User, error) {
users := []*model.User{}
for rows.Next() {
var user model.User
err := rows.Scan(
&user.ID,
&user.Name,
&user.Mail,
&user.Username,
&user.Password,
)
if err != nil {
return nil, err
}
users = append(users, &user)
}
return users, nil
}
func (us *UserStore) GetByID(id int) (*model.User, error) {
query := us.Q().Select(userColumns...).
From("users").
Where(sq.Eq{"id": id})
rows, err := query.Query()
if err != nil {
return nil, err
}
defer rows.Close()
users, err := us.usersFromRows(rows)
if err != nil {
return nil, err
}
if len(users) == 0 {
return nil, sql.ErrNoRows
}
return users[0], nil
}
func (us *UserStore) Create(user *model.User) (*model.User, error) {
query := us.Q().Insert("users").
Columns(userColumns[1:]...).
Values(user.Name, user.Mail, user.Username, user.Password)
res, err := query.Exec()
if err != nil {
return nil, err
}
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
return us.GetByID(int(id))
}

View file

@ -0,0 +1,44 @@
package store
import (
"testing"
"git.ctrlz.es/mgdelacroix/craban/model"
"github.com/stretchr/testify/require"
)
func TestCreateUser(t *testing.T) {
th, teardown := NewTestHelper(t)
defer teardown()
user := &model.User{
Name: "John",
Mail: "john_doe@example.com",
Username: "john_doe",
Password: "mysupersecret",
}
newUser, err := th.store.User().Create(user)
require.NoError(t, err)
require.NotZero(t, newUser.ID)
require.Equal(t, user.Name, newUser.Name)
require.Equal(t, user.Mail, newUser.Mail)
require.Equal(t, user.Username, newUser.Username)
require.Equal(t, user.Password, newUser.Password)
}
func TestGetByID(t *testing.T) {
th, teardown := NewTestHelper(t)
defer teardown()
user := th.NewUser()
user2, err := th.store.User().GetByID(user.ID)
require.NoError(t, err)
require.Equal(t, user.ID, user2.ID)
require.Equal(t, user.Name, user2.Name)
require.Equal(t, user.Mail, user2.Mail)
require.Equal(t, user.Username, user2.Username)
require.Equal(t, user.Password, user2.Password)
}