Skip to content

Commit 4f21862

Browse files
authored
Backend #18
2 parents 50f41bd + 996d8ae commit 4f21862

22 files changed

+1934
-174
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-- +goose Up
2+
CREATE TABLE history (
3+
id INTEGER PRIMARY KEY AUTOINCREMENT,
4+
collection_id INTEGER,
5+
collection_name TEXT,
6+
endpoint_name TEXT,
7+
method TEXT NOT NULL,
8+
url TEXT NOT NULL,
9+
status_code INTEGER NOT NULL,
10+
duration INTEGER NOT NULL, -- duration in milliseconds
11+
response_size INTEGER DEFAULT 0,
12+
request_headers TEXT DEFAULT '{}',
13+
query_params TEXT DEFAULT '{}',
14+
request_body TEXT DEFAULT '',
15+
response_body TEXT DEFAULT '',
16+
response_headers TEXT DEFAULT '{}',
17+
executed_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
18+
);
19+
20+
CREATE INDEX idx_history_collection_id ON history(collection_id);
21+
CREATE INDEX idx_history_executed_at ON history(executed_at);
22+
CREATE INDEX idx_history_status_code ON history(status_code);
23+
24+
-- +goose Down
25+
DROP INDEX IF EXISTS idx_history_status_code;
26+
DROP INDEX IF EXISTS idx_history_executed_at;
27+
DROP INDEX IF EXISTS idx_history_collection_id;
28+
DROP TABLE IF EXISTS history;

db/queries/collections.sql

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
-- name: CreateCollection :one
22
INSERT INTO collections (name) VALUES (?) RETURNING *;
33

4-
-- name: GetAllCollections :many
5-
SELECT * FROM collections;
4+
-- name: GetCollectionsPaginated :many
5+
SELECT * FROM collections
6+
ORDER BY created_at DESC
7+
LIMIT ? OFFSET ?;
8+
9+
-- name: CountCollections :one
10+
SELECT COUNT(*) FROM collections;
611

712
-- name: UpdateCollectionName :one
813
UPDATE collections
@@ -13,3 +18,7 @@ RETURNING *;
1318
-- name: DeleteCollection :exec
1419
DELETE FROM collections
1520
WHERE id = ?;
21+
22+
-- name: GetCollection :one
23+
SELECT * FROM collections
24+
WHERE id = ?;

db/queries/history.sql

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
-- name: CreateHistoryEntry :one
2+
INSERT INTO history (
3+
collection_id, collection_name, endpoint_name,
4+
method, url, status_code, duration, response_size,
5+
request_headers, query_params, request_body,
6+
response_body, response_headers, executed_at
7+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
8+
RETURNING *;
9+
10+
-- name: GetHistoryById :one
11+
SELECT * FROM history
12+
WHERE id = ?;
13+
14+
-- name: GetHistoryByCollection :many
15+
SELECT id, endpoint_name, status_code, executed_at, url, method FROM history
16+
WHERE collection_id = ?
17+
ORDER BY executed_at DESC
18+
LIMIT ? OFFSET ?;
19+
20+
-- name: CountHistoryByCollection :one
21+
SELECT COUNT(*) FROM history
22+
WHERE collection_id = ?;
23+
24+
-- name: DeleteHistoryEntry :exec
25+
DELETE FROM history
26+
WHERE id = ?;
27+
28+
-- name: DeleteOldHistory :exec
29+
DELETE FROM history
30+
WHERE executed_at < datetime('now', '-30 days');

internal/collections/collections.go

Lines changed: 0 additions & 89 deletions
This file was deleted.

internal/collections/endpoints.go

Lines changed: 0 additions & 77 deletions
This file was deleted.

internal/collections/manager.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package collections
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
7+
"github.com/maniac-en/req/internal/crud"
8+
"github.com/maniac-en/req/internal/database"
9+
"github.com/maniac-en/req/internal/log"
10+
)
11+
12+
func NewCollectionsManager(db *database.Queries) *CollectionsManager {
13+
return &CollectionsManager{DB: db}
14+
}
15+
16+
func (c *CollectionsManager) Create(ctx context.Context, name string) (CollectionEntity, error) {
17+
if err := crud.ValidateName(name); err != nil {
18+
log.Debug("collection creation failed validation", "name", name)
19+
return CollectionEntity{}, crud.ErrInvalidInput
20+
}
21+
22+
log.Debug("creating collection", "name", name)
23+
collection, err := c.DB.CreateCollection(ctx, name)
24+
if err != nil {
25+
log.Error("failed to create collection", "name", name, "error", err)
26+
return CollectionEntity{}, err
27+
}
28+
29+
log.Info("created collection", "id", collection.ID, "name", collection.Name)
30+
return CollectionEntity{Collection: collection}, nil
31+
}
32+
33+
func (c *CollectionsManager) Read(ctx context.Context, id int64) (CollectionEntity, error) {
34+
if err := crud.ValidateID(id); err != nil {
35+
log.Debug("collection read failed validation", "id", id)
36+
return CollectionEntity{}, crud.ErrInvalidInput
37+
}
38+
39+
log.Debug("reading collection", "id", id)
40+
collection, err := c.DB.GetCollection(ctx, id)
41+
if err != nil {
42+
if err == sql.ErrNoRows {
43+
log.Debug("collection not found", "id", id)
44+
return CollectionEntity{}, crud.ErrNotFound
45+
}
46+
log.Error("failed to read collection", "id", id, "error", err)
47+
return CollectionEntity{}, err
48+
}
49+
50+
return CollectionEntity{Collection: collection}, nil
51+
}
52+
53+
func (c *CollectionsManager) Update(ctx context.Context, id int64, name string) (CollectionEntity, error) {
54+
if err := crud.ValidateID(id); err != nil {
55+
log.Debug("collection update failed ID validation", "id", id)
56+
return CollectionEntity{}, crud.ErrInvalidInput
57+
}
58+
if err := crud.ValidateName(name); err != nil {
59+
log.Debug("collection update failed name validation", "name", name)
60+
return CollectionEntity{}, crud.ErrInvalidInput
61+
}
62+
63+
log.Debug("updating collection", "id", id, "name", name)
64+
collection, err := c.DB.UpdateCollectionName(ctx, database.UpdateCollectionNameParams{
65+
Name: name,
66+
ID: id,
67+
})
68+
if err != nil {
69+
if err == sql.ErrNoRows {
70+
log.Debug("collection not found for update", "id", id)
71+
return CollectionEntity{}, crud.ErrNotFound
72+
}
73+
log.Error("failed to update collection", "id", id, "name", name, "error", err)
74+
return CollectionEntity{}, err
75+
}
76+
77+
log.Info("updated collection", "id", collection.ID, "name", collection.Name)
78+
return CollectionEntity{Collection: collection}, nil
79+
}
80+
81+
func (c *CollectionsManager) Delete(ctx context.Context, id int64) error {
82+
if err := crud.ValidateID(id); err != nil {
83+
log.Debug("collection delete failed validation", "id", id)
84+
return crud.ErrInvalidInput
85+
}
86+
87+
log.Debug("deleting collection", "id", id)
88+
err := c.DB.DeleteCollection(ctx, id)
89+
if err != nil {
90+
log.Error("failed to delete collection", "id", id, "error", err)
91+
return err
92+
}
93+
94+
log.Info("deleted collection", "id", id)
95+
return nil
96+
}
97+
98+
func (c *CollectionsManager) List(ctx context.Context) ([]CollectionEntity, error) {
99+
log.Debug("listing all collections with default pagination")
100+
paginated, err := c.ListPaginated(ctx, 50, 0)
101+
if err != nil {
102+
return nil, err
103+
}
104+
return paginated.Collections, nil
105+
}
106+
107+
func (c *CollectionsManager) ListPaginated(ctx context.Context, limit, offset int64) (*PaginatedCollections, error) {
108+
log.Debug("listing paginated collections", "limit", limit, "offset", offset)
109+
110+
total, err := c.DB.CountCollections(ctx)
111+
if err != nil {
112+
log.Error("failed to count collections", "error", err)
113+
return nil, err
114+
}
115+
116+
collections, err := c.DB.GetCollectionsPaginated(ctx, database.GetCollectionsPaginatedParams{
117+
Limit: limit,
118+
Offset: offset,
119+
})
120+
if err != nil {
121+
log.Error("failed to get paginated collections", "limit", limit, "offset", offset, "error", err)
122+
return nil, err
123+
}
124+
125+
entities := make([]CollectionEntity, len(collections))
126+
for i, collection := range collections {
127+
entities[i] = CollectionEntity{Collection: collection}
128+
}
129+
130+
hasNext := offset+int64(len(collections)) < total
131+
hasPrev := offset > 0
132+
133+
log.Debug("retrieved paginated collections", "total", total, "returned", len(entities), "has_next", hasNext, "has_prev", hasPrev)
134+
135+
return &PaginatedCollections{
136+
Collections: entities,
137+
Total: total,
138+
Offset: offset,
139+
Limit: limit,
140+
HasNext: hasNext,
141+
HasPrev: hasPrev,
142+
}, nil
143+
}

0 commit comments

Comments
 (0)