repo: add some sql for events
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build and test / Build (push) Successful in 2m29s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build and test / Build (push) Successful in 2m29s
				
			This commit is contained in:
		
							
								
								
									
										41
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								README.md
									
									
									
									
									
								
							@ -421,7 +421,7 @@ The following basic use cases are to be implemented at the first time.
 | 
			
		||||
 | 
			
		||||
- [X] A user signs up
 | 
			
		||||
- [X] A user logs in
 | 
			
		||||
- [] A user lists their events (pagination)
 | 
			
		||||
- [X] A user lists their events (pagination)
 | 
			
		||||
- [] A user sees the detail of an event (description, members, amount)
 | 
			
		||||
- [] A user sees the expenses of an event (total amount, personal expenses, pagination)
 | 
			
		||||
- [] A user sees the detail of an expense: (time, amount, payers, recipients)
 | 
			
		||||
@ -430,7 +430,7 @@ The following basic use cases are to be implemented at the first time.
 | 
			
		||||
- [] A user deletes an expense (may handle some extra access control)
 | 
			
		||||
- [] A user restore a deleted expense
 | 
			
		||||
- [] A user can pay the debt to other members
 | 
			
		||||
- [X] A user creates an event
 | 
			
		||||
- [X] A user creates an event (and participate to it)
 | 
			
		||||
- [] A user updates the event info
 | 
			
		||||
- [] A user invites another user by sending a mail with a token.
 | 
			
		||||
- [] A user joins an event by accepting an invitation
 | 
			
		||||
@ -449,3 +449,40 @@ work on other aspects. For example:
 | 
			
		||||
- ex. Trip journal...
 | 
			
		||||
 | 
			
		||||
Stop dreaming... Just do the simple stuff first!
 | 
			
		||||
 | 
			
		||||
### 2024/10/18
 | 
			
		||||
 | 
			
		||||
I spent some time to figure out this one! But I don't actually need it for now.
 | 
			
		||||
So I just keep it here:
 | 
			
		||||
 | 
			
		||||
```SQL
 | 
			
		||||
SELECT
 | 
			
		||||
    e.id,
 | 
			
		||||
    e.name,
 | 
			
		||||
    e.description,
 | 
			
		||||
    e.created_at,
 | 
			
		||||
    json_build_object(
 | 
			
		||||
        'id', o.id,
 | 
			
		||||
        'first_name', o.first_name,
 | 
			
		||||
        'last_name', o.last_name
 | 
			
		||||
    ) AS owner,
 | 
			
		||||
    json_agg(
 | 
			
		||||
        json_build_object(
 | 
			
		||||
            'id', u.id,
 | 
			
		||||
            'first_name', u.first_name,
 | 
			
		||||
            'last_name', u.last_name
 | 
			
		||||
        )
 | 
			
		||||
    ) AS users  -- Aggregation for users in the event
 | 
			
		||||
FROM "event" e
 | 
			
		||||
JOIN "participation" p ON p.event_id = e.id  -- participation linked with the event
 | 
			
		||||
JOIN "user" u ON u.id = p.user_id            -- and the query user
 | 
			
		||||
JOIN "user" o ON o.id = e.owner_id           -- get the owner info
 | 
			
		||||
WHERE e.id IN (
 | 
			
		||||
    SELECT pt.event_id FROM participation pt WHERE pt.user_id = $1
 | 
			
		||||
    -- consider the events participated by user_id
 | 
			
		||||
)
 | 
			
		||||
GROUP BY
 | 
			
		||||
    e.id, e.name, e.description, e.created_at,
 | 
			
		||||
    o.id, o.first_name, o.last_name;
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										58
									
								
								internal/howmuch/adapter/repo/sqlc/event.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								internal/howmuch/adapter/repo/sqlc/event.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
			
		||||
-- name: InsertEvent :one
 | 
			
		||||
INSERT INTO "event" (
 | 
			
		||||
    name, description, total_amount, default_currency, owner_id, created_at, updated_at
 | 
			
		||||
) VALUES ( $1, $2, $3, $4, $5, $6, $7 )
 | 
			
		||||
RETURNING *;
 | 
			
		||||
 | 
			
		||||
-- name: ListEventsByUserID :many
 | 
			
		||||
SELECT
 | 
			
		||||
    e.id,
 | 
			
		||||
    e.name,
 | 
			
		||||
    e.description,
 | 
			
		||||
    e.created_at,
 | 
			
		||||
    json_build_object(
 | 
			
		||||
        'id', o.id,
 | 
			
		||||
        'first_name', o.first_name,
 | 
			
		||||
        'last_name', o.last_name
 | 
			
		||||
    ) AS owner
 | 
			
		||||
FROM "event" e
 | 
			
		||||
JOIN "participation" p ON p.event_id = e.id  -- participation linked with the event
 | 
			
		||||
JOIN "user" o ON o.id = e.owner_id           -- get the owner info
 | 
			
		||||
WHERE e.id IN (
 | 
			
		||||
    SELECT pt.event_id FROM participation pt WHERE pt.user_id = $1 -- consider the events participated by user_id
 | 
			
		||||
)
 | 
			
		||||
GROUP BY
 | 
			
		||||
    e.id, e.name, e.description, e.created_at,
 | 
			
		||||
    o.id, o.first_name, o.last_name;
 | 
			
		||||
 | 
			
		||||
-- name: GetEventByID :one
 | 
			
		||||
SELECT
 | 
			
		||||
    e.id,
 | 
			
		||||
    e.name,
 | 
			
		||||
    e.description,
 | 
			
		||||
    e.total_amount,
 | 
			
		||||
    e.default_currency,
 | 
			
		||||
    e.created_at,
 | 
			
		||||
    e.updated_at,
 | 
			
		||||
    json_build_object(
 | 
			
		||||
        'id', o.id,
 | 
			
		||||
        'first_name', o.first_name,
 | 
			
		||||
        'last_name', o.last_name
 | 
			
		||||
    ) AS owner,
 | 
			
		||||
    json_agg(
 | 
			
		||||
        json_build_object(
 | 
			
		||||
            'id', u.id,
 | 
			
		||||
            'first_name', u.first_name,
 | 
			
		||||
            'last_name', u.last_name
 | 
			
		||||
        )
 | 
			
		||||
    ) AS users  -- Aggregation for users in the event
 | 
			
		||||
FROM "event" e
 | 
			
		||||
JOIN "participation" p ON p.event_id = e.id  -- participation linked with the event
 | 
			
		||||
JOIN "user" u ON u.id = p.user_id            -- and the query user
 | 
			
		||||
JOIN "user" o ON o.id = e.owner_id           -- get the owner info
 | 
			
		||||
WHERE e.id = $1
 | 
			
		||||
GROUP BY
 | 
			
		||||
    e.id, e.name, e.description, e.created_at, e.updated_at,
 | 
			
		||||
    e.total_amount, e.default_currency,
 | 
			
		||||
    o.id, o.first_name, o.last_name;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										174
									
								
								internal/howmuch/adapter/repo/sqlc/event.sql.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								internal/howmuch/adapter/repo/sqlc/event.sql.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,174 @@
 | 
			
		||||
// Code generated by sqlc. DO NOT EDIT.
 | 
			
		||||
// versions:
 | 
			
		||||
//   sqlc v1.27.0
 | 
			
		||||
// source: event.sql
 | 
			
		||||
 | 
			
		||||
package sqlc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"database/sql"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const getEventByID = `-- name: GetEventByID :one
 | 
			
		||||
SELECT
 | 
			
		||||
    e.id,
 | 
			
		||||
    e.name,
 | 
			
		||||
    e.description,
 | 
			
		||||
    e.total_amount,
 | 
			
		||||
    e.default_currency,
 | 
			
		||||
    e.created_at,
 | 
			
		||||
    e.updated_at,
 | 
			
		||||
    json_build_object(
 | 
			
		||||
        'id', o.id,
 | 
			
		||||
        'first_name', o.first_name,
 | 
			
		||||
        'last_name', o.last_name
 | 
			
		||||
    ) AS owner,
 | 
			
		||||
    json_agg(
 | 
			
		||||
        json_build_object(
 | 
			
		||||
            'id', u.id,
 | 
			
		||||
            'first_name', u.first_name,
 | 
			
		||||
            'last_name', u.last_name
 | 
			
		||||
        )
 | 
			
		||||
    ) AS users  -- Aggregation for users in the event
 | 
			
		||||
FROM "event" e
 | 
			
		||||
JOIN "participation" p ON p.event_id = e.id  -- participation linked with the event
 | 
			
		||||
JOIN "user" u ON u.id = p.user_id            -- and the query user
 | 
			
		||||
JOIN "user" o ON o.id = e.owner_id           -- get the owner info
 | 
			
		||||
WHERE e.id = $1
 | 
			
		||||
GROUP BY
 | 
			
		||||
    e.id, e.name, e.description, e.created_at, e.updated_at,
 | 
			
		||||
    e.total_amount, e.default_currency,
 | 
			
		||||
    o.id, o.first_name, o.last_name
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
type GetEventByIDRow struct {
 | 
			
		||||
	ID              int32
 | 
			
		||||
	Name            string
 | 
			
		||||
	Description     sql.NullString
 | 
			
		||||
	TotalAmount     sql.NullInt32
 | 
			
		||||
	DefaultCurrency string
 | 
			
		||||
	CreatedAt       time.Time
 | 
			
		||||
	UpdatedAt       time.Time
 | 
			
		||||
	Owner           json.RawMessage
 | 
			
		||||
	Users           json.RawMessage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q *Queries) GetEventByID(ctx context.Context, id int32) (GetEventByIDRow, error) {
 | 
			
		||||
	row := q.db.QueryRowContext(ctx, getEventByID, id)
 | 
			
		||||
	var i GetEventByIDRow
 | 
			
		||||
	err := row.Scan(
 | 
			
		||||
		&i.ID,
 | 
			
		||||
		&i.Name,
 | 
			
		||||
		&i.Description,
 | 
			
		||||
		&i.TotalAmount,
 | 
			
		||||
		&i.DefaultCurrency,
 | 
			
		||||
		&i.CreatedAt,
 | 
			
		||||
		&i.UpdatedAt,
 | 
			
		||||
		&i.Owner,
 | 
			
		||||
		&i.Users,
 | 
			
		||||
	)
 | 
			
		||||
	return i, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const insertEvent = `-- name: InsertEvent :one
 | 
			
		||||
INSERT INTO "event" (
 | 
			
		||||
    name, description, total_amount, default_currency, owner_id, created_at, updated_at
 | 
			
		||||
) VALUES ( $1, $2, $3, $4, $5, $6, $7 )
 | 
			
		||||
RETURNING id, name, description, default_currency, owner_id, created_at, updated_at, total_amount
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
type InsertEventParams struct {
 | 
			
		||||
	Name            string
 | 
			
		||||
	Description     sql.NullString
 | 
			
		||||
	TotalAmount     sql.NullInt32
 | 
			
		||||
	DefaultCurrency string
 | 
			
		||||
	OwnerID         int32
 | 
			
		||||
	CreatedAt       time.Time
 | 
			
		||||
	UpdatedAt       time.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q *Queries) InsertEvent(ctx context.Context, arg InsertEventParams) (Event, error) {
 | 
			
		||||
	row := q.db.QueryRowContext(ctx, insertEvent,
 | 
			
		||||
		arg.Name,
 | 
			
		||||
		arg.Description,
 | 
			
		||||
		arg.TotalAmount,
 | 
			
		||||
		arg.DefaultCurrency,
 | 
			
		||||
		arg.OwnerID,
 | 
			
		||||
		arg.CreatedAt,
 | 
			
		||||
		arg.UpdatedAt,
 | 
			
		||||
	)
 | 
			
		||||
	var i Event
 | 
			
		||||
	err := row.Scan(
 | 
			
		||||
		&i.ID,
 | 
			
		||||
		&i.Name,
 | 
			
		||||
		&i.Description,
 | 
			
		||||
		&i.DefaultCurrency,
 | 
			
		||||
		&i.OwnerID,
 | 
			
		||||
		&i.CreatedAt,
 | 
			
		||||
		&i.UpdatedAt,
 | 
			
		||||
		&i.TotalAmount,
 | 
			
		||||
	)
 | 
			
		||||
	return i, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const listEventsByUserID = `-- name: ListEventsByUserID :many
 | 
			
		||||
SELECT
 | 
			
		||||
    e.id,
 | 
			
		||||
    e.name,
 | 
			
		||||
    e.description,
 | 
			
		||||
    e.created_at,
 | 
			
		||||
    json_build_object(
 | 
			
		||||
        'id', o.id,
 | 
			
		||||
        'first_name', o.first_name,
 | 
			
		||||
        'last_name', o.last_name
 | 
			
		||||
    ) AS owner
 | 
			
		||||
FROM "event" e
 | 
			
		||||
JOIN "participation" p ON p.event_id = e.id  -- participation linked with the event
 | 
			
		||||
JOIN "user" o ON o.id = e.owner_id           -- get the owner info
 | 
			
		||||
WHERE e.id IN (
 | 
			
		||||
    SELECT pt.event_id FROM participation pt WHERE pt.user_id = $1 -- consider the events participated by user_id
 | 
			
		||||
)
 | 
			
		||||
GROUP BY
 | 
			
		||||
    e.id, e.name, e.description, e.created_at,
 | 
			
		||||
    o.id, o.first_name, o.last_name
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
type ListEventsByUserIDRow struct {
 | 
			
		||||
	ID          int32
 | 
			
		||||
	Name        string
 | 
			
		||||
	Description sql.NullString
 | 
			
		||||
	CreatedAt   time.Time
 | 
			
		||||
	Owner       json.RawMessage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q *Queries) ListEventsByUserID(ctx context.Context, userID int32) ([]ListEventsByUserIDRow, error) {
 | 
			
		||||
	rows, err := q.db.QueryContext(ctx, listEventsByUserID, userID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer rows.Close()
 | 
			
		||||
	var items []ListEventsByUserIDRow
 | 
			
		||||
	for rows.Next() {
 | 
			
		||||
		var i ListEventsByUserIDRow
 | 
			
		||||
		if err := rows.Scan(
 | 
			
		||||
			&i.ID,
 | 
			
		||||
			&i.Name,
 | 
			
		||||
			&i.Description,
 | 
			
		||||
			&i.CreatedAt,
 | 
			
		||||
			&i.Owner,
 | 
			
		||||
		); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		items = append(items, i)
 | 
			
		||||
	}
 | 
			
		||||
	if err := rows.Close(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := rows.Err(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return items, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								internal/howmuch/adapter/repo/sqlc/participation.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								internal/howmuch/adapter/repo/sqlc/participation.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
-- name: InsertParticipation :one
 | 
			
		||||
INSERT INTO participation (
 | 
			
		||||
    user_id, event_id, invited_by_user_id, created_at, updated_at
 | 
			
		||||
) VALUES ($1, $2, $3, $4, $5)
 | 
			
		||||
RETURNING *;
 | 
			
		||||
							
								
								
									
										47
									
								
								internal/howmuch/adapter/repo/sqlc/participation.sql.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								internal/howmuch/adapter/repo/sqlc/participation.sql.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
// Code generated by sqlc. DO NOT EDIT.
 | 
			
		||||
// versions:
 | 
			
		||||
//   sqlc v1.27.0
 | 
			
		||||
// source: participation.sql
 | 
			
		||||
 | 
			
		||||
package sqlc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"database/sql"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const insertParticipation = `-- name: InsertParticipation :one
 | 
			
		||||
INSERT INTO participation (
 | 
			
		||||
    user_id, event_id, invited_by_user_id, created_at, updated_at
 | 
			
		||||
) VALUES ($1, $2, $3, $4, $5)
 | 
			
		||||
RETURNING id, user_id, event_id, invited_by_user_id, created_at, updated_at
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
type InsertParticipationParams struct {
 | 
			
		||||
	UserID          int32
 | 
			
		||||
	EventID         int32
 | 
			
		||||
	InvitedByUserID sql.NullInt32
 | 
			
		||||
	CreatedAt       time.Time
 | 
			
		||||
	UpdatedAt       time.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q *Queries) InsertParticipation(ctx context.Context, arg InsertParticipationParams) (Participation, error) {
 | 
			
		||||
	row := q.db.QueryRowContext(ctx, insertParticipation,
 | 
			
		||||
		arg.UserID,
 | 
			
		||||
		arg.EventID,
 | 
			
		||||
		arg.InvitedByUserID,
 | 
			
		||||
		arg.CreatedAt,
 | 
			
		||||
		arg.UpdatedAt,
 | 
			
		||||
	)
 | 
			
		||||
	var i Participation
 | 
			
		||||
	err := row.Scan(
 | 
			
		||||
		&i.ID,
 | 
			
		||||
		&i.UserID,
 | 
			
		||||
		&i.EventID,
 | 
			
		||||
		&i.InvitedByUserID,
 | 
			
		||||
		&i.CreatedAt,
 | 
			
		||||
		&i.UpdatedAt,
 | 
			
		||||
	)
 | 
			
		||||
	return i, err
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,2 @@
 | 
			
		||||
ALTER TABLE "participation"
 | 
			
		||||
ADD CONSTRAINT unique_user_event UNIQUE ("user_id", "event_id");
 | 
			
		||||
		Reference in New Issue
	
	Block a user