feat: connect to db and sample query

This commit is contained in:
ysandler 2025-03-17 17:55:17 -05:00
parent 815a3b2856
commit 83545fb854
9 changed files with 83 additions and 46 deletions

View File

@ -0,0 +1,13 @@
-- I DO NOT KNOW IF THIS WORKS --
-- I AM PLAYING ARROUND WITH START UP SCRIPTS FOR THE CONTAINER --
-- Drop existing roles/users if they exist
DROP ROLE IF EXISTS admin;
DROP USER IF EXISTS admin;
-- Create admin user with strong password using bcrypt
CREATE USER admin WITH PASSWORD 'password';
-- Grant all privileges
ALTER ROLE admin SUPERUSER;
GRANT ALL PRIVILEGES TO admin;

3
.env
View File

@ -4,5 +4,6 @@ DB_NAME=worklog
DB_HOST=localhost
DB_PORT=5432
DB_EXPOSED_PORT=6767
DB_TZ=America/Chicago
VOLUME_ROOT="./container_volume"
VOLUME_ROOT="./.container_volume"

View File

@ -2,8 +2,10 @@ package db
import (
"fmt"
"log"
"os"
"github.com/joho/godotenv"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
@ -11,37 +13,48 @@ import (
var DB *gorm.DB
func getEnv(key string) string {
if value, ok := os.LookupEnv(key); ok {
log.Printf("Loading environment variables...")
err := godotenv.Load()
if err != nil {
log.Fatal(fmt.Sprintf("Error loading .env file: %v", err))
}
value := os.Getenv(key)
if value != "" {
return value
}
panic(fmt.Sprintf("Missing environment variable: %s", key))
}
func Init() *gorm.DB {
func Init() (*gorm.DB, error) {
if DB != nil {
return DB
return DB, nil
}
connectionString := fmt.Sprintf("host=%s user=%s password=%s dbname=%s host=%s port=%s TimeZone=%s",
getEnv("DB_HOST"),
log.Println("Initializing database connection...")
connectionString := fmt.Sprintf("user=%s password=%s dbname=%s host=%s port=%s TimeZone=%s",
getEnv("DB_USER"),
getEnv("DB_PASSWORD"),
getEnv("DB_NAME"),
getEnv("DB_HOST"),
getEnv("DB_PORT"),
getEnv("DB_EXPOSED_PORT"),
getEnv("DB_TZ"))
log.Printf("Database connection string: %s", connectionString)
db, err := gorm.Open(postgres.Open(connectionString), &gorm.Config{})
if err != nil {
panic(fmt.Errorf("failed to connect to database: %v", err))
return nil, err
}
sqlDB, err := db.DB()
if err != nil {
panic(err)
return nil, err
}
sqlDB.SetMaxOpenConns(10)
sqlDB.SetMaxIdleConns(5)
DB = db
return DB
log.Println("Database connection established successfully")
return db, nil
}

View File

@ -1,4 +1,3 @@
version: '3'
services:
postgresdb:
image: postgres:latest
@ -6,15 +5,14 @@ services:
ports:
- "${DB_EXPOSED_PORT}:${DB_PORT}"
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: worklog
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
volumes:
- "${VOLUME_ROOT}/db:/var/lib/postgresql/data"
- "${VOLUME_ROOT}/scripts:/docker-entrypoint-initdb.d/"
env_file:
- ./.env
depends_on:
- postgresdb
networks:
postgres-network:

View File

@ -9,12 +9,12 @@ import (
type User struct {
gorm.Model
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:uuid_generate_v4()"`
FirstName string
LastName string
Email string
PhoneNumber string
CreatedAt time.Time
UpdatedAt time.Time
FirstName string `gorm:"size:255"`
LastName string `gorm:"size:255"`
Email string `gorm:"unique;not null;size:255"`
PhoneNumber string `gorm:"size:255"`
CreatedAt time.Time `gorm:"default:now()"`
UpdatedAt time.Time `gorm:"default:now()"`
}
type DevUser struct {
@ -30,21 +30,21 @@ type ClientUser struct {
type ClientUser_Project_Join struct {
gorm.Model
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:uuid_generate_v4()"`
ClientId uuid.UUID
ProjectId uuid.UUID
CreatedAt time.Time
UpdatedAt time.Time
IsStakeholder bool
Notes string
ClientId uuid.UUID `gorm:"foreignKey:ClientId;index:clientIdProjectIndex" `
ProjectId uuid.UUID `gorm:"foreignKey:ProjectId;index:projectIdClientIndex"`
CreatedAt time.Time `gorm:"default:now()"`
UpdatedAt time.Time `gorm:"default:now()"`
IsStakeholder bool `gorm:"size:1"`
Notes string `gorm:"type:text"`
}
type DevUser_Project_Join struct {
gorm.Model
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:uuid_generate_v4()"`
ClientId uuid.UUID
ProjectId uuid.UUID
CreatedAt time.Time
UpdatedAt time.Time
IsLead bool
Notes string
ClientId uuid.UUID `gorm:"foreignKey:ClientId;index:clientIdDevIndex" `
ProjectId uuid.UUID `gorm:"foreignKey:ProjectId;index:projectIdDevIndex"`
CreatedAt time.Time `gorm:"default:now()"`
UpdatedAt time.Time `gorm:"default:now()"`
IsLead bool `gorm:"size:1"`
Notes string `gorm:"type:text"`
}

4
go.mod
View File

@ -5,6 +5,8 @@ go 1.23.2
require (
github.com/gofiber/fiber/v3 v3.0.0-beta.4
github.com/google/uuid v1.6.0
github.com/joho/godotenv v1.5.1
gorm.io/driver/postgres v1.5.11
gorm.io/gorm v1.25.12
)
@ -20,7 +22,6 @@ require (
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
@ -33,5 +34,4 @@ require (
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
gorm.io/driver/postgres v1.5.11 // indirect
)

4
go.sum
View File

@ -25,10 +25,10 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=

16
main.go
View File

@ -1,6 +1,7 @@
package main
import (
"context"
"log"
"github.com/gofiber/fiber/v3"
@ -9,11 +10,22 @@ import (
)
func main() {
if err := db.Init(); err != nil {
DB, err := db.Init()
if err != nil {
log.Fatal(err)
}
repo := repository.GetUserRepo(db.DB)
repo := repository.GetUserRepo(DB)
ctx := context.Background()
users, totalUserCount, err := repo.List(ctx, 0, 10)
if err != nil {
log.Println(err)
}
log.Printf("Fetched %d users", len(users))
log.Printf("%d total users", totalUserCount)
app := fiber.New()

View File

@ -55,13 +55,13 @@ func (r *UserRepository) Delete(ctx context.Context, id uuid.UUID) error {
return r.db.WithContext(ctx).Delete(&user).Error
}
func (r *UserRepository) List(ctx context.Context, offset int, limit int) ([]entities.User, int64) {
func (r *UserRepository) List(ctx context.Context, offset int, limit int) ([]entities.User, int64, error) {
var users []entities.User
var totalUserCount int64
query := r.db.WithContext(ctx).Model(&users).Where("1 = 1") // All Users
query.Count(&totalUserCount) // Count of All Users
query.Offset(offset).Limit(limit).Find(&users) // Filtered Users
if err := r.db.WithContext(ctx).Where("1 = 1").Count(&totalUserCount).Offset(offset).Limit(limit); err != nil {
return nil, 0, err.Error
}
return users, totalUserCount
return users, totalUserCount, nil
}