Skip to content

Commit

Permalink
feat: postgres service
Browse files Browse the repository at this point in the history
  • Loading branch information
litsynp committed Jul 25, 2023
1 parent f662474 commit 7038589
Show file tree
Hide file tree
Showing 23 changed files with 430 additions and 275 deletions.
1 change: 1 addition & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
DATABASE_URL=
KAKAO_REST_API_KEY=
KAKAO_REDIRECT_URI=
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Set up database
run: docker-compose -f docker-compose-test.yml up -d

- name: Set up Go
uses: actions/setup-go@v4
with:
Expand Down
1 change: 1 addition & 0 deletions db/migrations/000001_create_users_table.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS users;
26 changes: 26 additions & 0 deletions db/migrations/000001_create_users_table.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
nickname VARCHAR(20) NOT NULL,
fullname VARCHAR(20) NOT NULL,
fb_provider_type VARCHAR(50),
fb_uid VARCHAR(255),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);

ALTER TABLE
users
ADD
CONSTRAINT users_email_uix UNIQUE (email);

ALTER TABLE
users
ADD
CONSTRAINT users_fb_uid_uix UNIQUE (fb_uid);

CREATE INDEX users_email_idx ON users (email);

CREATE INDEX users_fb_uid_idx ON users (fb_uid);
32 changes: 32 additions & 0 deletions docker-compose-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
version: "3.7"

services:
db_test:
image: postgres:11.5-alpine
ports:
- "5455:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=pets_next_door_api_test
volumes:
- pg_pets_next_door_api_db_test:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5

migrate:
image: migrate/migrate:v4.7.0
depends_on:
db_test:
condition: service_healthy
volumes:
- ./db/migrations:/db/migrations
command:
[ "-path", "/db/migrations", "-database", "postgresql://postgres:postgres@db_test:5432/pets_next_door_api_test?sslmode=disable", "up" ]
restart: on-failure

volumes:
pg_pets_next_door_api_db_test:
12 changes: 0 additions & 12 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,5 @@ services:
volumes:
- pg_pets_next_door_api_db:/var/lib/postgresql/data

db_test:
image: postgres:11.5-alpine
ports:
- "5455:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=pets_next_door_api_test
volumes:
- pg_pets_next_door_api_db_test:/var/lib/postgresql/data

volumes:
pg_pets_next_door_api_db:
pg_pets_next_door_api_db_test:
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ require (
require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/lib/pq v1.10.9 // indirect
go.uber.org/atomic v1.7.0 // indirect
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
)

Expand All @@ -25,6 +29,7 @@ require (
cloud.google.com/go/longrunning v0.4.2 // indirect
cloud.google.com/go/storage v1.30.1 // indirect
github.com/go-playground/validator v9.31.0+incompatible
github.com/golang-migrate/migrate/v4 v4.16.2
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
Expand Down
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator v9.31.0+incompatible h1:UA72EPEogEnq76ehGdEDp4Mit+3FDh548oRqwVgNsHA=
github.com/go-playground/validator v9.31.0+incompatible/go.mod h1:yrEkQXlcI+PugkyDjY2bRrL/UBU4f3rvrgkN3V8JEig=
github.com/golang-migrate/migrate/v4 v4.16.2 h1:8coYbMKUyInrFk1lfGfRovTLAW7PhWp8qQDT2iKfuoA=
github.com/golang-migrate/migrate/v4 v4.16.2/go.mod h1:pfcJX4nPHaVdc5nmdCikFBWtm+UBpiZjRNNsyBbp0/o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
Expand Down Expand Up @@ -86,17 +88,25 @@ github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5
github.com/googleapis/gax-go/v2 v2.10.0 h1:ebSgKfMxynOdxw8QQuFOKMgomqeLGPqNLQox2bo42zg=
github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand All @@ -108,6 +118,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
Expand Down
6 changes: 6 additions & 0 deletions internal/configs/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (

var Port = os.Getenv("PORT")

var DatabaseURL = os.Getenv("DATABASE_URL")

var KakaoRestAPIKey = os.Getenv("KAKAO_REST_API_KEY")
var KakaoRedirectURI = os.Getenv("KAKAO_REDIRECT_URI")

Expand All @@ -18,6 +20,10 @@ func init() {
Port = "8080"
}

if DatabaseURL == "" {
panic("DATABASE_URL is required")
}

if KakaoRestAPIKey == "" {
panic("KAKAO_REST_API_KEY is required")
}
Expand Down
46 changes: 46 additions & 0 deletions internal/database/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package database

import (
"database/sql"
"log"

"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
)

func Open(databaseURL string) (*DB, error) {
db, err := sql.Open("postgres", databaseURL)
if err != nil {
return nil, err
}
return &DB{DB: db, databaseURL: databaseURL}, nil
}

func (db *DB) Close() error {
return db.DB.Close()
}

func (db *DB) Migrate() {

m, err := migrate.New(
"file://db/migrations",
db.databaseURL,
)

if err != nil {
log.Fatal(err)
}

if err := m.Up(); err != nil && err != migrate.ErrNoChange {
log.Fatal(err)
}
}

func (db *DB) Begin() (*Tx, error) {
tx, err := db.DB.Begin()
if err != nil {
return nil, err
}
return &Tx{tx}, nil
}
12 changes: 12 additions & 0 deletions internal/database/type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package database

import "database/sql"

type DB struct {
DB *sql.DB
databaseURL string
}

type Tx struct {
*sql.Tx
}
137 changes: 137 additions & 0 deletions internal/database/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package database

import "github.com/pet-sitter/pets-next-door-api/internal/models"

func (tx *Tx) CreateUser(user *models.User) (*models.User, error) {
err := tx.QueryRow(`
INSERT INTO
users
(
email,
nickname,
fullname,
password,
fb_provider_type,
fb_uid,
created_at,
updated_at
)
VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW())
RETURNING id, created_at, updated_at
`,
user.Email,
user.Nickname,
user.Fullname,
user.Password,
user.FirebaseProviderType,
user.FirebaseUID,
).Scan(&user.ID, &user.CreatedAt, &user.UpdatedAt)

if err != nil {
return nil, err
}

return user, nil
}

func (tx *Tx) FindUserByEmail(email string) (*models.User, error) {
user := &models.User{}

err := tx.QueryRow(`
SELECT
id,
email,
nickname,
fullname,
fb_provider_type,
fb_uid,
created_at,
updated_at
FROM
users
WHERE
email = $1
`,
email,
).Scan(
&user.ID,
&user.Email,
&user.Nickname,
&user.Fullname,
&user.FirebaseProviderType,
&user.FirebaseUID,
&user.CreatedAt,
&user.UpdatedAt,
)

if err != nil {
return nil, err
}

return user, nil
}

func (tx *Tx) FindUserByUID(uid string) (*models.User, error) {
user := &models.User{}

err := tx.QueryRow(`
SELECT
id,
email,
nickname,
fullname,
fb_provider_type,
fb_uid,
created_at,
updated_at
FROM
users
WHERE
fb_uid = $1
`,
uid,
).Scan(
&user.ID,
&user.Email,
&user.Nickname,
&user.Fullname,
&user.FirebaseProviderType,
&user.FirebaseUID,
&user.CreatedAt,
&user.UpdatedAt,
)

if err != nil {
return nil, err
}

return user, nil
}

func (tx *Tx) UpdateUserByUID(uid string, nickname string) (*models.User, error) {
user := &models.User{}

err := tx.QueryRow(`
UPDATE
users
SET
nickname = $1,
updated_at = NOW()
WHERE
fb_uid = $2
RETURNING id, created_at, updated_at
`,
nickname,
uid,
).Scan(
&user.ID,
&user.CreatedAt,
&user.UpdatedAt,
)

if err != nil {
return nil, err
}

return user, nil
}
5 changes: 0 additions & 5 deletions internal/infra/database/type.go

This file was deleted.

14 changes: 14 additions & 0 deletions internal/models/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package models

type User struct {
ID int `field:"id"`
Email string `field:"email"`
Password string `field:"password"`
Nickname string `field:"nickname"`
Fullname string `field:"fullname"`
FirebaseProviderType string `field:"fb_provider_type"`
FirebaseUID string `field:"fb_uid"`
CreatedAt string `field:"created_at"`
UpdatedAt string `field:"updated_at"`
DeletedAt string `field:"deleted_at"`
}
Loading

0 comments on commit 7038589

Please sign in to comment.