This commit is contained in:
m
2026-07-13 00:15:39 +02:00
parent e59fde6a48
commit 7dc53ea99f
5 changed files with 308 additions and 0 deletions
@@ -0,0 +1,3 @@
DROP TABLE IF EXISTS file_tags;
DROP TABLE IF EXISTS tags;
@@ -0,0 +1,19 @@
-- VaultDrop 003: tags table
CREATE TABLE tags (
id TEXT PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
parent_tag_id TEXT,
tag_name TEXT NOT NULL, -- exemple: Brice, vélo, facture ...
tag_type TEXT NOT NULL DEFAULT 'none', -- exemple: entity, none, folder
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_parent_tag FOREIGN KEY(parent_tag_id) REFERENCES tags(id)
);
CREATE TABLE file_tags (
id TEXT PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
tag_id TEXT,
file_id TEXT,
CONSTRAINT fk_tag FOREIGN KEY(tag_id) REFERENCES tags(id),
CONSTRAINT fk_file FOREIGN KEY(file_id) REFERENCES files(id)
)
+16
View File
@@ -5,6 +5,7 @@
package db
import (
"database/sql"
"time"
)
@@ -19,3 +20,18 @@ type File struct {
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type FileTag struct {
ID string `json:"id"`
TagID sql.NullString `json:"tag_id"`
FileID sql.NullString `json:"file_id"`
}
type Tag struct {
ID string `json:"id"`
ParentTagID sql.NullString `json:"parent_tag_id"`
TagName string `json:"tag_name"`
TagType string `json:"tag_type"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
+41
View File
@@ -0,0 +1,41 @@
-- name: CreateTag :one
INSERT INTO tags (id, tag_name, tag_type)
VALUES ($1, $2, $3)
RETURNING *;
-- name: GetTag :one
SELECT * FROM tags
WHERE id = $1;
-- name: GetTagByName :one
SELECT * FROM tags
WHERE tag_name = $1;
-- name: ListTags :many
SELECT * FROM tags
ORDER BY tag_name ASC;
-- name: DeleteTag :exec
DELETE FROM tags
WHERE id = $1;
-- name: AddTagToFile :exec
INSERT INTO file_tags (id, tag_id, file_id)
VALUES ($1, $2, $3)
ON CONFLICT DO NOTHING;
-- name: RemoveTagFromFile :exec
DELETE FROM file_tags
WHERE tag_id = $1 AND file_id = $2;
-- name: GetTagsByFileID :many
SELECT t.* FROM tags t
JOIN file_tags ft ON t.id = ft.tag_id
WHERE ft.file_id = $1
ORDER BY t.tag_name ASC;
-- name: GetFilesByTagID :many
SELECT f.* FROM files f
JOIN file_tags ft ON f.id = ft.file_id
WHERE ft.tag_id = $1
ORDER BY f.created_at DESC;
+229
View File
@@ -0,0 +1,229 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: tags.sql
package db
import (
"context"
"database/sql"
)
const addTagToFile = `-- name: AddTagToFile :exec
INSERT INTO file_tags (id, tag_id, file_id)
VALUES ($1, $2, $3)
ON CONFLICT DO NOTHING
`
type AddTagToFileParams struct {
ID string `json:"id"`
TagID sql.NullString `json:"tag_id"`
FileID sql.NullString `json:"file_id"`
}
func (q *Queries) AddTagToFile(ctx context.Context, arg AddTagToFileParams) error {
_, err := q.db.ExecContext(ctx, addTagToFile, arg.ID, arg.TagID, arg.FileID)
return err
}
const createTag = `-- name: CreateTag :one
INSERT INTO tags (id, tag_name, tag_type)
VALUES ($1, $2, $3)
RETURNING id, parent_tag_id, tag_name, tag_type, created_at, updated_at
`
type CreateTagParams struct {
ID string `json:"id"`
TagName string `json:"tag_name"`
TagType string `json:"tag_type"`
}
func (q *Queries) CreateTag(ctx context.Context, arg CreateTagParams) (Tag, error) {
row := q.db.QueryRowContext(ctx, createTag, arg.ID, arg.TagName, arg.TagType)
var i Tag
err := row.Scan(
&i.ID,
&i.ParentTagID,
&i.TagName,
&i.TagType,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const deleteTag = `-- name: DeleteTag :exec
DELETE FROM tags
WHERE id = $1
`
func (q *Queries) DeleteTag(ctx context.Context, id string) error {
_, err := q.db.ExecContext(ctx, deleteTag, id)
return err
}
const getFilesByTagID = `-- name: GetFilesByTagID :many
SELECT f.id, f.name, f.mime_type, f.size, f.storage_key, f.checksum, f.ocr_text, f.created_at, f.updated_at FROM files f
JOIN file_tags ft ON f.id = ft.file_id
WHERE ft.tag_id = $1
ORDER BY f.created_at DESC
`
func (q *Queries) GetFilesByTagID(ctx context.Context, tagID sql.NullString) ([]File, error) {
rows, err := q.db.QueryContext(ctx, getFilesByTagID, tagID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []File
for rows.Next() {
var i File
if err := rows.Scan(
&i.ID,
&i.Name,
&i.MimeType,
&i.Size,
&i.StorageKey,
&i.Checksum,
&i.OcrText,
&i.CreatedAt,
&i.UpdatedAt,
); 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
}
const getTag = `-- name: GetTag :one
SELECT id, parent_tag_id, tag_name, tag_type, created_at, updated_at FROM tags
WHERE id = $1
`
func (q *Queries) GetTag(ctx context.Context, id string) (Tag, error) {
row := q.db.QueryRowContext(ctx, getTag, id)
var i Tag
err := row.Scan(
&i.ID,
&i.ParentTagID,
&i.TagName,
&i.TagType,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getTagByName = `-- name: GetTagByName :one
SELECT id, parent_tag_id, tag_name, tag_type, created_at, updated_at FROM tags
WHERE tag_name = $1
`
func (q *Queries) GetTagByName(ctx context.Context, tagName string) (Tag, error) {
row := q.db.QueryRowContext(ctx, getTagByName, tagName)
var i Tag
err := row.Scan(
&i.ID,
&i.ParentTagID,
&i.TagName,
&i.TagType,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getTagsByFileID = `-- name: GetTagsByFileID :many
SELECT t.id, t.parent_tag_id, t.tag_name, t.tag_type, t.created_at, t.updated_at FROM tags t
JOIN file_tags ft ON t.id = ft.tag_id
WHERE ft.file_id = $1
ORDER BY t.tag_name ASC
`
func (q *Queries) GetTagsByFileID(ctx context.Context, fileID sql.NullString) ([]Tag, error) {
rows, err := q.db.QueryContext(ctx, getTagsByFileID, fileID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Tag
for rows.Next() {
var i Tag
if err := rows.Scan(
&i.ID,
&i.ParentTagID,
&i.TagName,
&i.TagType,
&i.CreatedAt,
&i.UpdatedAt,
); 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
}
const listTags = `-- name: ListTags :many
SELECT id, parent_tag_id, tag_name, tag_type, created_at, updated_at FROM tags
ORDER BY tag_name ASC
`
func (q *Queries) ListTags(ctx context.Context) ([]Tag, error) {
rows, err := q.db.QueryContext(ctx, listTags)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Tag
for rows.Next() {
var i Tag
if err := rows.Scan(
&i.ID,
&i.ParentTagID,
&i.TagName,
&i.TagType,
&i.CreatedAt,
&i.UpdatedAt,
); 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
}
const removeTagFromFile = `-- name: RemoveTagFromFile :exec
DELETE FROM file_tags
WHERE tag_id = $1 AND file_id = $2
`
type RemoveTagFromFileParams struct {
TagID sql.NullString `json:"tag_id"`
FileID sql.NullString `json:"file_id"`
}
func (q *Queries) RemoveTagFromFile(ctx context.Context, arg RemoveTagFromFileParams) error {
_, err := q.db.ExecContext(ctx, removeTagFromFile, arg.TagID, arg.FileID)
return err
}