Compare commits
7 Commits
761babfa1a
...
828d611f4d
| Author | SHA1 | Date | |
|---|---|---|---|
| 828d611f4d | |||
| 82bd446a85 | |||
| 24075e5a76 | |||
| 27184bf17a | |||
| ec17dfb0ce | |||
| 6e3328ca83 | |||
| 164ea9a6c8 |
@ -2,11 +2,13 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -48,3 +50,30 @@ func transaction(handler func(context.Context, pgx.Tx) (statusCode int, err erro
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle database error
|
||||||
|
func handleDBError(errIn error) (statusCode int, err error) {
|
||||||
|
if errIn == nil {
|
||||||
|
statusCode = http.StatusOK
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(errIn, pgx.ErrNoRows) {
|
||||||
|
err = fmt.Errorf("not found")
|
||||||
|
statusCode = http.StatusNotFound
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var pgErr *pgconn.PgError
|
||||||
|
if errors.As(errIn, &pgErr) {
|
||||||
|
switch pgErr.Code {
|
||||||
|
case "22P02", "22007": // Invalid data format
|
||||||
|
err = fmt.Errorf("%s", pgErr.Message)
|
||||||
|
statusCode = http.StatusBadRequest
|
||||||
|
return
|
||||||
|
case "23505": // Unique constraint violation
|
||||||
|
err = fmt.Errorf("already exists")
|
||||||
|
statusCode = http.StatusConflict
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return http.StatusInternalServerError, errIn
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
@ -8,7 +9,7 @@ import (
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
IsAdmin bool `json:"is_admin"`
|
IsAdmin bool `json:"isAdmin"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MIME struct {
|
type MIME struct {
|
||||||
@ -16,50 +17,95 @@ type MIME struct {
|
|||||||
Extension string `json:"extension"`
|
Extension string `json:"extension"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Category struct {
|
type (
|
||||||
ID string `json:"id"`
|
CategoryCore struct {
|
||||||
Name string `json:"name"`
|
ID string `json:"id"`
|
||||||
Color pgtype.Text `json:"color"`
|
Name string `json:"name"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
Color pgtype.Text `json:"color"`
|
||||||
Creator User `json:"creator"`
|
}
|
||||||
}
|
CategoryItem struct {
|
||||||
|
CategoryCore
|
||||||
|
}
|
||||||
|
CategoryFull struct {
|
||||||
|
CategoryCore
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
Creator User `json:"creator"`
|
||||||
|
Notes pgtype.Text `json:"notes"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
type File struct {
|
type (
|
||||||
ID string `json:"id"`
|
FileCore struct {
|
||||||
Name pgtype.Text `json:"name"`
|
ID string `json:"id"`
|
||||||
MIME MIME `json:"mime"`
|
Name pgtype.Text `json:"name"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
MIME MIME `json:"mime"`
|
||||||
Creator User `json:"creator"`
|
}
|
||||||
}
|
FileItem struct {
|
||||||
|
FileCore
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
Creator User `json:"creator"`
|
||||||
|
}
|
||||||
|
FileFull struct {
|
||||||
|
FileCore
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
Creator User `json:"creator"`
|
||||||
|
Notes pgtype.Text `json:"notes"`
|
||||||
|
Metadata *json.RawMessage `json:"metadata"`
|
||||||
|
Tags []TagCore `json:"tags"`
|
||||||
|
Viewed int `json:"viewed"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
type Tag struct {
|
type (
|
||||||
ID string `json:"id"`
|
TagCore struct {
|
||||||
Name string `json:"name"`
|
ID string `json:"id"`
|
||||||
Color pgtype.Text `json:"color"`
|
Name string `json:"name"`
|
||||||
Category Category `json:"category"`
|
Color pgtype.Text `json:"color"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
}
|
||||||
Creator User `json:"creator"`
|
TagItem struct {
|
||||||
}
|
TagCore
|
||||||
|
Category CategoryCore `json:"category"`
|
||||||
|
}
|
||||||
|
TagFull struct {
|
||||||
|
TagCore
|
||||||
|
Category CategoryCore `json:"category"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
Creator User `json:"creator"`
|
||||||
|
Notes pgtype.Text `json:"notes"`
|
||||||
|
UsedIncl int `json:"usedIncl"`
|
||||||
|
UsedExcl int `json:"usedExcl"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
type Autotag struct {
|
type Autotag struct {
|
||||||
TriggerTag Tag `json:"trigger_tag"`
|
TriggerTag TagCore `json:"triggerTag"`
|
||||||
AddTag Tag `json:"add_tag"`
|
AddTag TagCore `json:"addTag"`
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"isActive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pool struct {
|
type (
|
||||||
ID string `json:"id"`
|
PoolCore struct {
|
||||||
Name string `json:"name"`
|
ID string `json:"id"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
Name string `json:"name"`
|
||||||
Creator User `json:"creator"`
|
}
|
||||||
}
|
PoolItem struct {
|
||||||
|
PoolCore
|
||||||
|
}
|
||||||
|
PoolFull struct {
|
||||||
|
PoolCore
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
Creator User `json:"creator"`
|
||||||
|
Notes pgtype.Text `json:"notes"`
|
||||||
|
Viewed int `json:"viewed"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
UserAgent string `json:"user_agent"`
|
UserAgent string `json:"userAgent"`
|
||||||
StartedAt time.Time `json:"started_at"`
|
StartedAt time.Time `json:"startedAt"`
|
||||||
ExpiresAt time.Time `json:"expires_at"`
|
ExpiresAt time.Time `json:"expiresAt"`
|
||||||
LastActivity time.Time `json:"last_activity"`
|
LastActivity time.Time `json:"lastActivity"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pagination struct {
|
type Pagination struct {
|
||||||
|
|||||||
@ -80,6 +80,20 @@ CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public;
|
|||||||
COMMENT ON EXTENSION "uuid-ossp" IS 'generate universally unique identifiers (UUIDs)';
|
COMMENT ON EXTENSION "uuid-ossp" IS 'generate universally unique identifiers (UUIDs)';
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: uuid_extract_timestamp(uuid); Type: FUNCTION; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE FUNCTION public.uuid_extract_timestamp(uuid_val uuid) RETURNS timestamp with time zone
|
||||||
|
LANGUAGE sql IMMUTABLE
|
||||||
|
AS $$
|
||||||
|
SELECT to_timestamp(
|
||||||
|
('x' || LEFT(REPLACE(uuid_val::TEXT, '-', ''), 12))::BIT(48)::BIGINT
|
||||||
|
/ 1000.0
|
||||||
|
);
|
||||||
|
$$;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: uuid_v7(timestamp with time zone); Type: FUNCTION; Schema: public; Owner: -
|
-- Name: uuid_v7(timestamp with time zone); Type: FUNCTION; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@ -290,7 +304,7 @@ CREATE TABLE data.files (
|
|||||||
mime_id smallint NOT NULL,
|
mime_id smallint NOT NULL,
|
||||||
datetime timestamp with time zone DEFAULT clock_timestamp() NOT NULL,
|
datetime timestamp with time zone DEFAULT clock_timestamp() NOT NULL,
|
||||||
notes text,
|
notes text,
|
||||||
metadata jsonb NOT NULL,
|
metadata jsonb,
|
||||||
creator_id smallint NOT NULL
|
creator_id smallint NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user