Files
query-orchestration/internal/database/repository/folders.sql.go
T
Jay Brown 72de690894 Merged in feature/chatbot1 (pull request #223)
Chatbot functionality

* baseline working

* missing test file

* more tests
2026-05-07 20:56:18 +00:00

806 lines
21 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: folders.sql
package repository
import (
"context"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
const countDocumentsByFolder = `-- name: CountDocumentsByFolder :one
SELECT COUNT(*) as total FROM documents
WHERE folderId = $1
`
// CountDocumentsByFolder
//
// SELECT COUNT(*) as total FROM documents
// WHERE folderId = $1
func (q *Queries) CountDocumentsByFolder(ctx context.Context, folderid *uuid.UUID) (int64, error) {
row := q.db.QueryRow(ctx, countDocumentsByFolder, folderid)
var total int64
err := row.Scan(&total)
return total, err
}
const countDocumentsInFolderTree = `-- name: CountDocumentsInFolderTree :one
WITH RECURSIVE folder_tree AS (
SELECT id FROM folders WHERE id = $1
UNION ALL
SELECT f.id FROM folders f
JOIN folder_tree ft ON f.parentId = ft.id
)
SELECT COUNT(*) FROM documents WHERE folderId IN (SELECT id FROM folder_tree)
`
// Count documents in a folder tree to check before deletion without include_documents
//
// WITH RECURSIVE folder_tree AS (
// SELECT id FROM folders WHERE id = $1
// UNION ALL
// SELECT f.id FROM folders f
// JOIN folder_tree ft ON f.parentId = ft.id
// )
// SELECT COUNT(*) FROM documents WHERE folderId IN (SELECT id FROM folder_tree)
func (q *Queries) CountDocumentsInFolderTree(ctx context.Context, folderID *uuid.UUID) (int64, error) {
row := q.db.QueryRow(ctx, countDocumentsInFolderTree, folderID)
var count int64
err := row.Scan(&count)
return count, err
}
const createFolder = `-- name: CreateFolder :one
INSERT INTO folders (path, parentId, clientId, createdBy)
VALUES ($1, $2, $3, $4)
RETURNING id, path, parentid, clientid, createdat, createdby
`
type CreateFolderParams struct {
Path string `db:"path"`
Parentid *uuid.UUID `db:"parentid"`
Clientid string `db:"clientid"`
Createdby string `db:"createdby"`
}
// CreateFolder
//
// INSERT INTO folders (path, parentId, clientId, createdBy)
// VALUES ($1, $2, $3, $4)
// RETURNING id, path, parentid, clientid, createdat, createdby
func (q *Queries) CreateFolder(ctx context.Context, arg *CreateFolderParams) (*Folder, error) {
row := q.db.QueryRow(ctx, createFolder,
arg.Path,
arg.Parentid,
arg.Clientid,
arg.Createdby,
)
var i Folder
err := row.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
)
return &i, err
}
const deleteDocumentUploadsInFolderTree = `-- name: DeleteDocumentUploadsInFolderTree :exec
WITH RECURSIVE folder_tree AS (
SELECT id FROM folders WHERE id = $1
UNION ALL
SELECT f.id FROM folders f
JOIN folder_tree ft ON f.parentId = ft.id
)
DELETE FROM documentUploads WHERE folder_id IN (SELECT id FROM folder_tree)
`
// @sqlc-vet-disable
// Delete documentUploads rows that reference folders in the tree
//
// WITH RECURSIVE folder_tree AS (
// SELECT id FROM folders WHERE id = $1
// UNION ALL
// SELECT f.id FROM folders f
// JOIN folder_tree ft ON f.parentId = ft.id
// )
// DELETE FROM documentUploads WHERE folder_id IN (SELECT id FROM folder_tree)
func (q *Queries) DeleteDocumentUploadsInFolderTree(ctx context.Context, folderID *uuid.UUID) error {
_, err := q.db.Exec(ctx, deleteDocumentUploadsInFolderTree, folderID)
return err
}
const getClientRootFolder = `-- name: GetClientRootFolder :one
SELECT id, path, parentid, clientid, createdat, createdby FROM folders
WHERE clientId = $1 AND path = '/'
`
// Returns the root folder "/" for a client
//
// SELECT id, path, parentid, clientid, createdat, createdby FROM folders
// WHERE clientId = $1 AND path = '/'
func (q *Queries) GetClientRootFolder(ctx context.Context, clientid string) (*Folder, error) {
row := q.db.QueryRow(ctx, getClientRootFolder, clientid)
var i Folder
err := row.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
)
return &i, err
}
const getDocumentIDsInFolderTree = `-- name: GetDocumentIDsInFolderTree :many
WITH RECURSIVE folder_tree AS (
SELECT id FROM folders WHERE id = $1
UNION ALL
SELECT f.id FROM folders f
JOIN folder_tree ft ON f.parentId = ft.id
)
SELECT id FROM documents WHERE folderId IN (SELECT id FROM folder_tree)
`
// Get all document IDs in a folder tree for cascade deletion
//
// WITH RECURSIVE folder_tree AS (
// SELECT id FROM folders WHERE id = $1
// UNION ALL
// SELECT f.id FROM folders f
// JOIN folder_tree ft ON f.parentId = ft.id
// )
// SELECT id FROM documents WHERE folderId IN (SELECT id FROM folder_tree)
func (q *Queries) GetDocumentIDsInFolderTree(ctx context.Context, folderID *uuid.UUID) ([]uuid.UUID, error) {
rows, err := q.db.Query(ctx, getDocumentIDsInFolderTree, folderID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []uuid.UUID{}
for rows.Next() {
var id uuid.UUID
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getDocumentIDsInFolderTreeForClient = `-- name: GetDocumentIDsInFolderTreeForClient :many
WITH RECURSIVE folder_tree AS (
SELECT id FROM folders
WHERE id = $2::uuid
AND clientId = $1::varchar
UNION ALL
SELECT f.id FROM folders f
JOIN folder_tree ft ON f.parentId = ft.id
WHERE f.clientId = $1::varchar
)
SELECT id FROM documents
WHERE folderId IN (SELECT id FROM folder_tree)
AND clientId = $1::varchar
`
type GetDocumentIDsInFolderTreeForClientParams struct {
ClientID string `db:"client_id"`
FolderID uuid.UUID `db:"folder_id"`
}
// Chatbot-scoped recursive folder tree walk. Plan §5 mandates that the
// clientId filter applies at every recursive step AND at the final
// document selection so a cross-client root cannot leak documents.
//
// Step-by-step:
//
// - Base case: select the root folder only when its clientId matches.
//
// - Recursive case: descend through folders.parentId, requiring the
// child folder's clientId to match. A folder owned by a different
// client cannot enter the CTE even if its parent did (which it
// cannot, because the base case already rejects cross-client roots).
//
// - Final selection: documents must reside in folder_tree AND share
// the same clientId, defending against any future case where a
// document row references a folder owned by a different client.
//
// WITH RECURSIVE folder_tree AS (
// SELECT id FROM folders
// WHERE id = $2::uuid
// AND clientId = $1::varchar
// UNION ALL
// SELECT f.id FROM folders f
// JOIN folder_tree ft ON f.parentId = ft.id
// WHERE f.clientId = $1::varchar
// )
// SELECT id FROM documents
// WHERE folderId IN (SELECT id FROM folder_tree)
// AND clientId = $1::varchar
func (q *Queries) GetDocumentIDsInFolderTreeForClient(ctx context.Context, arg *GetDocumentIDsInFolderTreeForClientParams) ([]uuid.UUID, error) {
rows, err := q.db.Query(ctx, getDocumentIDsInFolderTreeForClient, arg.ClientID, arg.FolderID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []uuid.UUID{}
for rows.Next() {
var id uuid.UUID
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getDocumentsByFolder = `-- name: GetDocumentsByFolder :many
SELECT id, clientid, hash, batch_id, filename, folderid, originalpath, file_size_bytes, custom_schema_id FROM documents
WHERE folderId = $1
ORDER BY id
`
// GetDocumentsByFolder
//
// SELECT id, clientid, hash, batch_id, filename, folderid, originalpath, file_size_bytes, custom_schema_id FROM documents
// WHERE folderId = $1
// ORDER BY id
func (q *Queries) GetDocumentsByFolder(ctx context.Context, folderid *uuid.UUID) ([]*Document, error) {
rows, err := q.db.Query(ctx, getDocumentsByFolder, folderid)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*Document{}
for rows.Next() {
var i Document
if err := rows.Scan(
&i.ID,
&i.Clientid,
&i.Hash,
&i.BatchID,
&i.Filename,
&i.Folderid,
&i.Originalpath,
&i.FileSizeBytes,
&i.CustomSchemaID,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getDocumentsByFolderEnriched = `-- name: GetDocumentsByFolderEnriched :many
SELECT
d.id,
d.hash,
d.folderId,
d.filename,
d.originalPath,
d.file_size_bytes
FROM documents d
WHERE d.folderId = $1
ORDER BY d.id
`
type GetDocumentsByFolderEnrichedRow struct {
ID uuid.UUID `db:"id"`
Hash string `db:"hash"`
Folderid *uuid.UUID `db:"folderid"`
Filename *string `db:"filename"`
Originalpath *string `db:"originalpath"`
FileSizeBytes *int64 `db:"file_size_bytes"`
}
// Gets documents in a folder with all enriched metadata fields
//
// SELECT
// d.id,
// d.hash,
// d.folderId,
// d.filename,
// d.originalPath,
// d.file_size_bytes
// FROM documents d
// WHERE d.folderId = $1
// ORDER BY d.id
func (q *Queries) GetDocumentsByFolderEnriched(ctx context.Context, folderid *uuid.UUID) ([]*GetDocumentsByFolderEnrichedRow, error) {
rows, err := q.db.Query(ctx, getDocumentsByFolderEnriched, folderid)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*GetDocumentsByFolderEnrichedRow{}
for rows.Next() {
var i GetDocumentsByFolderEnrichedRow
if err := rows.Scan(
&i.ID,
&i.Hash,
&i.Folderid,
&i.Filename,
&i.Originalpath,
&i.FileSizeBytes,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getFolderByID = `-- name: GetFolderByID :one
SELECT id, path, parentid, clientid, createdat, createdby FROM folders
WHERE id = $1
`
// GetFolderByID
//
// SELECT id, path, parentid, clientid, createdat, createdby FROM folders
// WHERE id = $1
func (q *Queries) GetFolderByID(ctx context.Context, id uuid.UUID) (*Folder, error) {
row := q.db.QueryRow(ctx, getFolderByID, id)
var i Folder
err := row.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
)
return &i, err
}
const getFolderByPath = `-- name: GetFolderByPath :one
SELECT id, path, parentid, clientid, createdat, createdby FROM folders
WHERE clientId = $1 AND path = $2
`
type GetFolderByPathParams struct {
Clientid string `db:"clientid"`
Path string `db:"path"`
}
// GetFolderByPath
//
// SELECT id, path, parentid, clientid, createdat, createdby FROM folders
// WHERE clientId = $1 AND path = $2
func (q *Queries) GetFolderByPath(ctx context.Context, arg *GetFolderByPathParams) (*Folder, error) {
row := q.db.QueryRow(ctx, getFolderByPath, arg.Clientid, arg.Path)
var i Folder
err := row.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
)
return &i, err
}
const getFolderLabelCounts = `-- name: GetFolderLabelCounts :many
SELECT dl.label, COUNT(DISTINCT dl.documentId) as count
FROM documents d
INNER JOIN documentLabels dl ON d.id = dl.documentId
WHERE d.folderId = $1
GROUP BY dl.label
ORDER BY dl.label
`
type GetFolderLabelCountsRow struct {
Label string `db:"label"`
Count int64 `db:"count"`
}
// GetFolderLabelCounts
//
// SELECT dl.label, COUNT(DISTINCT dl.documentId) as count
// FROM documents d
// INNER JOIN documentLabels dl ON d.id = dl.documentId
// WHERE d.folderId = $1
// GROUP BY dl.label
// ORDER BY dl.label
func (q *Queries) GetFolderLabelCounts(ctx context.Context, folderid *uuid.UUID) ([]*GetFolderLabelCountsRow, error) {
rows, err := q.db.Query(ctx, getFolderLabelCounts, folderid)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*GetFolderLabelCountsRow{}
for rows.Next() {
var i GetFolderLabelCountsRow
if err := rows.Scan(&i.Label, &i.Count); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getFolderTree = `-- name: GetFolderTree :many
WITH RECURSIVE folder_tree AS (
-- Base case: start with the target folder
SELECT id, path, parentId, clientId, createdAt, createdBy
FROM folders
WHERE id = $1
UNION ALL
-- Recursive case: find all child folders
SELECT f.id, f.path, f.parentId, f.clientId, f.createdAt, f.createdBy
FROM folders f
INNER JOIN folder_tree ft ON f.parentId = ft.id
)
SELECT id, path, parentId, clientId, createdAt, createdBy
FROM folder_tree
ORDER BY path
`
type GetFolderTreeRow struct {
ID uuid.UUID `db:"id"`
Path string `db:"path"`
Parentid *uuid.UUID `db:"parentid"`
Clientid string `db:"clientid"`
Createdat pgtype.Timestamp `db:"createdat"`
Createdby string `db:"createdby"`
}
// GetFolderTree
//
// WITH RECURSIVE folder_tree AS (
// -- Base case: start with the target folder
// SELECT id, path, parentId, clientId, createdAt, createdBy
// FROM folders
// WHERE id = $1
//
// UNION ALL
//
// -- Recursive case: find all child folders
// SELECT f.id, f.path, f.parentId, f.clientId, f.createdAt, f.createdBy
// FROM folders f
// INNER JOIN folder_tree ft ON f.parentId = ft.id
// )
// SELECT id, path, parentId, clientId, createdAt, createdBy
// FROM folder_tree
// ORDER BY path
func (q *Queries) GetFolderTree(ctx context.Context, dollar_1 *uuid.UUID) ([]*GetFolderTreeRow, error) {
rows, err := q.db.Query(ctx, getFolderTree, dollar_1)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*GetFolderTreeRow{}
for rows.Next() {
var i GetFolderTreeRow
if err := rows.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getFolderTreeIDs = `-- name: GetFolderTreeIDs :many
WITH RECURSIVE folder_tree AS (
SELECT id, path FROM folders WHERE id = $1
UNION ALL
SELECT f.id, f.path FROM folders f
JOIN folder_tree ft ON f.parentId = ft.id
)
SELECT id, path FROM folder_tree
`
type GetFolderTreeIDsRow struct {
ID uuid.UUID `db:"id"`
Path string `db:"path"`
}
// Get all folder IDs in a folder tree (recursive) for cascade delete operations
//
// WITH RECURSIVE folder_tree AS (
// SELECT id, path FROM folders WHERE id = $1
// UNION ALL
// SELECT f.id, f.path FROM folders f
// JOIN folder_tree ft ON f.parentId = ft.id
// )
// SELECT id, path FROM folder_tree
func (q *Queries) GetFolderTreeIDs(ctx context.Context, folderID *uuid.UUID) ([]*GetFolderTreeIDsRow, error) {
rows, err := q.db.Query(ctx, getFolderTreeIDs, folderID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*GetFolderTreeIDsRow{}
for rows.Next() {
var i GetFolderTreeIDsRow
if err := rows.Scan(&i.ID, &i.Path); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getFoldersByClientID = `-- name: GetFoldersByClientID :many
SELECT id, path, parentid, clientid, createdat, createdby FROM folders
WHERE clientId = $1
ORDER BY path
`
// GetFoldersByClientID
//
// SELECT id, path, parentid, clientid, createdat, createdby FROM folders
// WHERE clientId = $1
// ORDER BY path
func (q *Queries) GetFoldersByClientID(ctx context.Context, clientid string) ([]*Folder, error) {
rows, err := q.db.Query(ctx, getFoldersByClientID, clientid)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*Folder{}
for rows.Next() {
var i Folder
if err := rows.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getFoldersByParentID = `-- name: GetFoldersByParentID :many
SELECT id, path, parentid, clientid, createdat, createdby FROM folders
WHERE parentId = $1
ORDER BY path
`
// GetFoldersByParentID
//
// SELECT id, path, parentid, clientid, createdat, createdby FROM folders
// WHERE parentId = $1
// ORDER BY path
func (q *Queries) GetFoldersByParentID(ctx context.Context, parentid *uuid.UUID) ([]*Folder, error) {
rows, err := q.db.Query(ctx, getFoldersByParentID, parentid)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*Folder{}
for rows.Next() {
var i Folder
if err := rows.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getRootFolders = `-- name: GetRootFolders :many
SELECT id, path, parentid, clientid, createdat, createdby FROM folders
WHERE clientId = $1 AND parentId IS NULL
ORDER BY path
`
// Returns folders with null parentId (should only be the "/" root folder for each client)
//
// SELECT id, path, parentid, clientid, createdat, createdby FROM folders
// WHERE clientId = $1 AND parentId IS NULL
// ORDER BY path
func (q *Queries) GetRootFolders(ctx context.Context, clientid string) ([]*Folder, error) {
rows, err := q.db.Query(ctx, getRootFolders, clientid)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*Folder{}
for rows.Next() {
var i Folder
if err := rows.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getTopLevelFolders = `-- name: GetTopLevelFolders :many
SELECT f.id, f.path, f.parentid, f.clientid, f.createdat, f.createdby FROM folders f
INNER JOIN folders root ON f.parentId = root.id
WHERE f.clientId = $1 AND root.path = '/'
ORDER BY f.path
`
// Returns folders that are direct children of the root folder "/"
// These are the user-visible top-level folders (e.g., /folder1, /folder2)
//
// SELECT f.id, f.path, f.parentid, f.clientid, f.createdat, f.createdby FROM folders f
// INNER JOIN folders root ON f.parentId = root.id
// WHERE f.clientId = $1 AND root.path = '/'
// ORDER BY f.path
func (q *Queries) GetTopLevelFolders(ctx context.Context, clientid string) ([]*Folder, error) {
rows, err := q.db.Query(ctx, getTopLevelFolders, clientid)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*Folder{}
for rows.Next() {
var i Folder
if err := rows.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const hardDeleteFolderTree = `-- name: HardDeleteFolderTree :execrows
WITH RECURSIVE folder_tree AS (
SELECT id FROM folders WHERE id = $1
UNION ALL
SELECT f.id FROM folders f
JOIN folder_tree ft ON f.parentId = ft.id
)
DELETE FROM folders WHERE id IN (SELECT id FROM folder_tree)
`
// @sqlc-vet-disable
// Delete all folders in the tree. PostgreSQL handles ordering within the CTE.
// Returns the number of rows deleted.
//
// WITH RECURSIVE folder_tree AS (
// SELECT id FROM folders WHERE id = $1
// UNION ALL
// SELECT f.id FROM folders f
// JOIN folder_tree ft ON f.parentId = ft.id
// )
// DELETE FROM folders WHERE id IN (SELECT id FROM folder_tree)
func (q *Queries) HardDeleteFolderTree(ctx context.Context, folderID *uuid.UUID) (int64, error) {
result, err := q.db.Exec(ctx, hardDeleteFolderTree, folderID)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const renameFolder = `-- name: RenameFolder :exec
UPDATE folders
SET path = $2
WHERE id = $1
`
type RenameFolderParams struct {
ID uuid.UUID `db:"id"`
Path string `db:"path"`
}
// RenameFolder
//
// UPDATE folders
// SET path = $2
// WHERE id = $1
func (q *Queries) RenameFolder(ctx context.Context, arg *RenameFolderParams) error {
_, err := q.db.Exec(ctx, renameFolder, arg.ID, arg.Path)
return err
}
const upsertFolder = `-- name: UpsertFolder :one
INSERT INTO folders (path, parentId, clientId, createdBy)
VALUES ($1, $2, $3, $4)
ON CONFLICT (clientId, path) DO UPDATE SET path = EXCLUDED.path
RETURNING id, path, parentid, clientid, createdat, createdby
`
type UpsertFolderParams struct {
Path string `db:"path"`
Parentid *uuid.UUID `db:"parentid"`
Clientid string `db:"clientid"`
Createdby string `db:"createdby"`
}
// Insert a folder if it doesn't exist, or return the existing one
// Used for auto-creating folder hierarchies during document upload
//
// INSERT INTO folders (path, parentId, clientId, createdBy)
// VALUES ($1, $2, $3, $4)
// ON CONFLICT (clientId, path) DO UPDATE SET path = EXCLUDED.path
// RETURNING id, path, parentid, clientid, createdat, createdby
func (q *Queries) UpsertFolder(ctx context.Context, arg *UpsertFolderParams) (*Folder, error) {
row := q.db.QueryRow(ctx, upsertFolder,
arg.Path,
arg.Parentid,
arg.Clientid,
arg.Createdby,
)
var i Folder
err := row.Scan(
&i.ID,
&i.Path,
&i.Parentid,
&i.Clientid,
&i.Createdat,
&i.Createdby,
)
return &i, err
}