102 lines
3.1 KiB
SQL
102 lines
3.1 KiB
SQL
ALTER TABLE tasks
|
|
ADD COLUMN deletion_started_at TIMESTAMPTZ,
|
|
ADD COLUMN deletion_reason VARCHAR(32);
|
|
|
|
CREATE INDEX tasks_deletion_pending
|
|
ON tasks(deletion_started_at)
|
|
WHERE deletion_started_at IS NOT NULL;
|
|
|
|
CREATE TABLE storage_objects (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
task_id UUID NOT NULL,
|
|
task_file_id UUID,
|
|
object_kind VARCHAR(32) NOT NULL,
|
|
state VARCHAR(20) NOT NULL DEFAULT 'staging',
|
|
backend VARCHAR(16) NOT NULL,
|
|
storage_endpoint_id UUID REFERENCES storage_endpoints(id) ON DELETE RESTRICT,
|
|
object_key TEXT NOT NULL,
|
|
storage_etag TEXT,
|
|
size_bytes BIGINT,
|
|
lease_owner UUID,
|
|
lease_until TIMESTAMPTZ,
|
|
delete_attempts INTEGER NOT NULL DEFAULT 0,
|
|
next_attempt_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
last_error TEXT,
|
|
published_at TIMESTAMPTZ,
|
|
deleted_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT storage_objects_kind_check
|
|
CHECK (object_kind IN ('result', 'zip_attempt', 'input', 'input_dir', 'legacy_zip')),
|
|
CONSTRAINT storage_objects_state_check
|
|
CHECK (state IN ('staging', 'published', 'delete_pending', 'deleted')),
|
|
CONSTRAINT storage_objects_backend_check
|
|
CHECK (backend IN ('s3', 'local', 'local_dir')),
|
|
CONSTRAINT storage_objects_attempts_check
|
|
CHECK (delete_attempts >= 0),
|
|
CONSTRAINT storage_objects_size_check
|
|
CHECK (size_bytes IS NULL OR size_bytes >= 0),
|
|
CONSTRAINT storage_objects_endpoint_check
|
|
CHECK (
|
|
(backend = 's3' AND storage_endpoint_id IS NOT NULL)
|
|
OR (backend IN ('local', 'local_dir') AND storage_endpoint_id IS NULL)
|
|
),
|
|
CONSTRAINT storage_objects_lease_pair_check
|
|
CHECK ((lease_owner IS NULL) = (lease_until IS NULL))
|
|
);
|
|
|
|
CREATE UNIQUE INDEX storage_objects_locator_unique
|
|
ON storage_objects(
|
|
backend,
|
|
COALESCE(storage_endpoint_id, '00000000-0000-0000-0000-000000000000'::uuid),
|
|
object_key
|
|
);
|
|
|
|
CREATE INDEX storage_objects_cleanup_ready
|
|
ON storage_objects(next_attempt_at, created_at)
|
|
WHERE state IN ('staging', 'delete_pending');
|
|
|
|
CREATE INDEX storage_objects_task
|
|
ON storage_objects(task_id, state);
|
|
|
|
INSERT INTO storage_objects (
|
|
task_id, task_file_id, object_kind, state,
|
|
backend, storage_endpoint_id, object_key, storage_etag,
|
|
size_bytes, published_at
|
|
)
|
|
SELECT
|
|
file.task_id,
|
|
file.id,
|
|
'result',
|
|
'published',
|
|
file.storage_backend,
|
|
file.storage_endpoint_id,
|
|
COALESCE(file.storage_key, file.storage_path),
|
|
file.storage_etag,
|
|
file.compressed_size,
|
|
COALESCE(file.completed_at, file.created_at)
|
|
FROM task_files AS file
|
|
WHERE file.status = 'completed'
|
|
AND COALESCE(file.storage_key, file.storage_path) IS NOT NULL
|
|
ON CONFLICT DO NOTHING;
|
|
|
|
INSERT INTO storage_objects (
|
|
task_id, object_kind, state,
|
|
backend, storage_endpoint_id, object_key, storage_etag,
|
|
size_bytes, published_at
|
|
)
|
|
SELECT
|
|
task.id,
|
|
'zip_attempt',
|
|
'published',
|
|
task.zip_storage_backend,
|
|
task.zip_storage_endpoint_id,
|
|
task.zip_storage_key,
|
|
task.zip_storage_etag,
|
|
task.zip_size,
|
|
COALESCE(task.completed_at, task.created_at)
|
|
FROM tasks AS task
|
|
WHERE task.zip_storage_backend IS NOT NULL
|
|
AND task.zip_storage_key IS NOT NULL
|
|
ON CONFLICT DO NOTHING;
|