Begin migration to sqlc

This commit is contained in:
2021-11-08 21:32:30 +00:00
parent f019c47d21
commit cf1bc70103
17 changed files with 427 additions and 72 deletions

View File

@ -1,5 +1,16 @@
CREATE TABLE budgets (
id char(26),
name text,
id char(26) NOT NULL,
name text NOT NULL,
last_modification timestamp with time zone
);
);
-- name: CreateBudget :one
INSERT INTO budgets
(id, name, last_modification)
VALUES ($1, $2, NOW())
RETURNING *;
-- name: GetBudgetsForUser :many
SELECT budgets.* FROM budgets
LEFT JOIN user_budgets ON budgets.id = user_budgets.budget_id
WHERE user_budgets.user_id = $1;

53
postgres/budgets.sql.go Normal file
View File

@ -0,0 +1,53 @@
// Code generated by sqlc. DO NOT EDIT.
// source: budgets.sql
package postgres
import (
"context"
)
const createBudget = `-- name: CreateBudget :one
INSERT INTO budgets
(id, name, last_modification)
VALUES ($1, $2, NOW())
RETURNING id, name, last_modification
`
type CreateBudgetParams struct {
ID string
Name string
}
func (q *Queries) CreateBudget(ctx context.Context, arg CreateBudgetParams) (Budget, error) {
row := q.db.QueryRow(ctx, createBudget, arg.ID, arg.Name)
var i Budget
err := row.Scan(&i.ID, &i.Name, &i.LastModification)
return i, err
}
const getBudgetsForUser = `-- name: GetBudgetsForUser :many
SELECT budgets.id, budgets.name, budgets.last_modification FROM budgets
LEFT JOIN user_budgets ON budgets.id = user_budgets.budget_id
WHERE user_budgets.user_id = $1
`
func (q *Queries) GetBudgetsForUser(ctx context.Context, userID string) ([]Budget, error) {
rows, err := q.db.Query(ctx, getBudgetsForUser, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Budget
for rows.Next() {
var i Budget
if err := rows.Scan(&i.ID, &i.Name, &i.LastModification); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}

View File

@ -1,6 +1,11 @@
package postgres
import "git.javil.eu/jacob1123/budgeteer"
import (
"context"
"database/sql"
"git.javil.eu/jacob1123/budgeteer"
)
// Budget returns a budget for a given id.
func (s *Repository) Budget(id string) (*budgeteer.Budget, error) {
@ -12,32 +17,27 @@ func (s *Repository) Budget(id string) (*budgeteer.Budget, error) {
return b, nil
}
func (s *Repository) BudgetsForUser(id string) ([]*budgeteer.Budget, error) {
user := &budgeteer.User{
ID: id,
}
err := s.DB.Model(&user).
Column("user.*", "Budgets").
Select()
func (s *Repository) BudgetsForUser(id string) ([]Budget, error) {
budgets, err := s.DB.GetBudgetsForUser(context.Background(), sql.NullString{id, true})
if err != nil {
return nil, err
}
return user.Budgets, nil
return budgets, nil
}
func (s *Repository) NewBudget(name string, userID string) (*budgeteer.Budget, error) {
b := &budgeteer.Budget{ID: s.IDGenerator.New(), Name: name}
err := s.DB.Insert(b)
func (s *Repository) NewBudget(name string, userID string) (Budget, error) {
b := CreateBudgetParams{ID: s.IDGenerator.New(), Name: name}
budget, err := s.DB.CreateBudget(context.Background(), b)
if err != nil {
return nil, err
}
ub := &budgeteer.UserBudget{UserID: userID, BudgetID: b.ID}
err = s.DB.Insert(ub)
ub := LinkBudgetToUserParams{UserID: userID, BudgetID: budget.ID}
_, err = s.DB.LinkBudgetToUser(context.Background(), ub)
if err != nil {
return nil, err
}
return b, nil
return budget, nil
}

17
postgres/conn.go Normal file
View File

@ -0,0 +1,17 @@
package postgres
import (
"context"
"fmt"
"github.com/jackc/pgx/v4"
)
// Connect to a database
func Connect(server string, user string, password string, database string) (*Queries, error) {
conn, err := pgx.Connect(context.Background(), fmt.Sprintf("postgresql://%s:%s@%s/%s", user, password, server, database))
if err != nil {
return nil, err
}
return New(conn), nil
}

View File

@ -1,14 +1,30 @@
package postgres
import "gopkg.in/pg.v5"
// Connect to a database
func Connect(server string, user string, password string, database string) *pg.DB {
db := pg.Connect(&pg.Options{
User: user,
Password: password,
Addr: server,
Database: database,
})
return db
}
// Code generated by sqlc. DO NOT EDIT.
package postgres
import (
"context"
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
)
type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
return &Queries{
db: tx,
}
}

25
postgres/models.go Normal file
View File

@ -0,0 +1,25 @@
// Code generated by sqlc. DO NOT EDIT.
package postgres
import (
"database/sql"
)
type Budget struct {
ID string
Name string
LastModification sql.NullTime
}
type User struct {
ID sql.NullString
Email sql.NullString
Name sql.NullString
Password sql.NullString
}
type UserBudget struct {
UserID string
BudgetID string
}

View File

@ -2,11 +2,10 @@ package postgres
import (
"git.javil.eu/jacob1123/budgeteer"
"gopkg.in/pg.v5"
)
// Repository represents a PostgreSQL implementation of all ModelServices
type Repository struct {
DB *pg.DB
DB *Queries
IDGenerator budgeteer.IDGenerator
}

View File

@ -1,4 +1,10 @@
CREATE TABLE user_budgets (
user_id char(26),
budget_id char(26)
);
user_id char(26) NOT NULL,
budget_id char(26) NOT NULL
);
-- name: LinkBudgetToUser :one
INSERT INTO user_budgets
(user_id, budget_id)
VALUES ($1, $2)
RETURNING *;

View File

@ -0,0 +1,27 @@
// Code generated by sqlc. DO NOT EDIT.
// source: user_budgets.sql
package postgres
import (
"context"
)
const linkBudgetToUser = `-- name: LinkBudgetToUser :one
INSERT INTO user_budgets
(user_id, budget_id)
VALUES ($1, $2)
RETURNING user_id, budget_id
`
type LinkBudgetToUserParams struct {
UserID string
BudgetID string
}
func (q *Queries) LinkBudgetToUser(ctx context.Context, arg LinkBudgetToUserParams) (UserBudget, error) {
row := q.db.QueryRow(ctx, linkBudgetToUser, arg.UserID, arg.BudgetID)
var i UserBudget
err := row.Scan(&i.UserID, &i.BudgetID)
return i, err
}

View File

@ -3,4 +3,18 @@ CREATE TABLE users (
email text,
name text,
password text
);
);
-- name: GetUserByUsername :one
SELECT * FROM users
WHERE email = $1;
-- name: GetUser :one
SELECT * FROM users
WHERE id = $1;
-- name: CreateUser :one
INSERT INTO users
(id, email, name, password)
VALUES ($1, $2, $3, $4)
RETURNING *;

74
postgres/users.sql.go Normal file
View File

@ -0,0 +1,74 @@
// Code generated by sqlc. DO NOT EDIT.
// source: users.sql
package postgres
import (
"context"
"database/sql"
)
const createUser = `-- name: CreateUser :one
INSERT INTO users
(id, email, name, password)
VALUES ($1, $2, $3, $4)
RETURNING id, email, name, password
`
type CreateUserParams struct {
ID sql.NullString
Email sql.NullString
Name sql.NullString
Password sql.NullString
}
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) {
row := q.db.QueryRow(ctx, createUser,
arg.ID,
arg.Email,
arg.Name,
arg.Password,
)
var i User
err := row.Scan(
&i.ID,
&i.Email,
&i.Name,
&i.Password,
)
return i, err
}
const getUser = `-- name: GetUser :one
SELECT id, email, name, password FROM users
WHERE id = $1
`
func (q *Queries) GetUser(ctx context.Context, id sql.NullString) (User, error) {
row := q.db.QueryRow(ctx, getUser, id)
var i User
err := row.Scan(
&i.ID,
&i.Email,
&i.Name,
&i.Password,
)
return i, err
}
const getUserByUsername = `-- name: GetUserByUsername :one
SELECT id, email, name, password FROM users
WHERE email = $1
`
func (q *Queries) GetUserByUsername(ctx context.Context, email sql.NullString) (User, error) {
row := q.db.QueryRow(ctx, getUserByUsername, email)
var i User
err := row.Scan(
&i.ID,
&i.Email,
&i.Name,
&i.Password,
)
return i, err
}

View File

@ -1,32 +0,0 @@
package postgres
import "git.javil.eu/jacob1123/budgeteer"
// User returns a user for a given id.
func (s *Repository) User(id string) (*budgeteer.User, error) {
u := &budgeteer.User{ID: id}
err := s.DB.Select(&u)
if err != nil {
return nil, err
}
return u, nil
}
// UserByUsername returns a user for a given username.
func (s *Repository) UserByUsername(username string) (*budgeteer.User, error) {
u := &budgeteer.User{Email: username}
err := s.DB.Model(&u).
Where("email = ?", username).
Limit(1).
Select()
if err != nil {
return nil, err
}
return u, nil
}
// CreateUser saves a user to the DB
func (s *Repository) CreateUser(user *budgeteer.User) error {
user.ID = s.IDGenerator.New()
return s.DB.Insert(user)
}