go first commit
This commit is contained in:
29
go_cloud/internal/database/database.go
Normal file
29
go_cloud/internal/database/database.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"go.b0esche.cloud/backend/internal/config"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/jackc/pgx/v5/stdlib"
|
||||
)
|
||||
|
||||
func Connect(cfg *config.Config) (*sql.DB, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
pool, err := pgxpool.New(ctx, cfg.DatabaseURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create pool: %w", err)
|
||||
}
|
||||
|
||||
if err := pool.Ping(ctx); err != nil {
|
||||
return nil, fmt.Errorf("failed to ping database: %w", err)
|
||||
}
|
||||
|
||||
db := stdlib.OpenDBFromPool(pool)
|
||||
|
||||
return db, nil
|
||||
}
|
||||
124
go_cloud/internal/database/db.go
Normal file
124
go_cloud/internal/database/db.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type DB struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
func New(db *sql.DB) *DB {
|
||||
return &DB{DB: db}
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID uuid.UUID
|
||||
Email string
|
||||
DisplayName string
|
||||
CreatedAt time.Time
|
||||
LastLoginAt *time.Time
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
ID uuid.UUID
|
||||
UserID uuid.UUID
|
||||
ExpiresAt time.Time
|
||||
RevokedAt *time.Time
|
||||
}
|
||||
|
||||
type Organization struct {
|
||||
ID uuid.UUID
|
||||
Name string
|
||||
Slug string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type Membership struct {
|
||||
UserID uuid.UUID
|
||||
OrgID uuid.UUID
|
||||
Role string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (db *DB) GetOrCreateUser(ctx context.Context, sub, email, name string) (*User, error) {
|
||||
var user User
|
||||
err := db.QueryRowContext(ctx, `
|
||||
INSERT INTO users (id, email, display_name)
|
||||
VALUES (gen_random_uuid(), $1, $2)
|
||||
ON CONFLICT (email) DO UPDATE SET
|
||||
display_name = EXCLUDED.display_name,
|
||||
last_login_at = NOW()
|
||||
RETURNING id, email, display_name, created_at, last_login_at
|
||||
`, email, name).Scan(&user.ID, &user.Email, &user.DisplayName, &user.CreatedAt, &user.LastLoginAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (db *DB) CreateSession(ctx context.Context, userID uuid.UUID, expiresAt time.Time) (*Session, error) {
|
||||
var session Session
|
||||
err := db.QueryRowContext(ctx, `
|
||||
INSERT INTO sessions (user_id, expires_at)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id, user_id, expires_at, revoked_at
|
||||
`, userID, expiresAt).Scan(&session.ID, &session.UserID, &session.ExpiresAt, &session.RevokedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &session, nil
|
||||
}
|
||||
|
||||
func (db *DB) GetSession(ctx context.Context, sessionID uuid.UUID) (*Session, error) {
|
||||
var session Session
|
||||
err := db.QueryRowContext(ctx, `
|
||||
SELECT id, user_id, expires_at, revoked_at
|
||||
FROM sessions
|
||||
WHERE id = $1
|
||||
`, sessionID).Scan(&session.ID, &session.UserID, &session.ExpiresAt, &session.RevokedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &session, nil
|
||||
}
|
||||
|
||||
func (db *DB) GetUserOrganizations(ctx context.Context, userID uuid.UUID) ([]Organization, error) {
|
||||
rows, err := db.QueryContext(ctx, `
|
||||
SELECT o.id, o.name, o.slug, o.created_at
|
||||
FROM organizations o
|
||||
JOIN memberships m ON o.id = m.org_id
|
||||
WHERE m.user_id = $1
|
||||
`, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var orgs []Organization
|
||||
for rows.Next() {
|
||||
var org Organization
|
||||
if err := rows.Scan(&org.ID, &org.Name, &org.Slug, &org.CreatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orgs = append(orgs, org)
|
||||
}
|
||||
return orgs, rows.Err()
|
||||
}
|
||||
|
||||
func (db *DB) GetUserMembership(ctx context.Context, userID, orgID uuid.UUID) (*Membership, error) {
|
||||
var membership Membership
|
||||
err := db.QueryRowContext(ctx, `
|
||||
SELECT user_id, org_id, role, created_at
|
||||
FROM memberships
|
||||
WHERE user_id = $1 AND org_id = $2
|
||||
`, userID, orgID).Scan(&membership.UserID, &membership.OrgID, &membership.Role, &membership.CreatedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &membership, nil
|
||||
}
|
||||
Reference in New Issue
Block a user