mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-04-20 06:28:14 -04:00
* backend rename complete * finalize Object refactor frontend + remove some exhaustive dep suppression + FIX INVALIDATE QUERY BUG
389 lines
11 KiB
Plaintext
389 lines
11 KiB
Plaintext
datasource db {
|
|
provider = "sqlite"
|
|
url = "file:dev.db"
|
|
}
|
|
|
|
generator client {
|
|
provider = "cargo prisma"
|
|
output = "../src/prisma.rs"
|
|
}
|
|
|
|
model SyncEvent {
|
|
id Int @id @default(autoincrement())
|
|
node_id Int
|
|
timestamp String
|
|
// individual record pub id OR compound many-to-many pub ids
|
|
record_id Bytes
|
|
// the type of operation, I.E: CREATE, UPDATE, DELETE as an enum
|
|
kind Int
|
|
// the column name for atomic update operations
|
|
column String?
|
|
// the new value for create/update operations, msgpack encoded
|
|
value String
|
|
|
|
node Node @relation(fields: [node_id], references: [id])
|
|
|
|
@@map("sync_event")
|
|
}
|
|
|
|
model Statistics {
|
|
id Int @id @default(autoincrement())
|
|
date_captured DateTime @default(now())
|
|
total_object_count Int @default(0)
|
|
library_db_size String @default("0")
|
|
total_bytes_used String @default("0")
|
|
total_bytes_capacity String @default("0")
|
|
total_unique_bytes String @default("0")
|
|
total_bytes_free String @default("0")
|
|
preview_media_bytes String @default("0")
|
|
|
|
@@map("statistics")
|
|
}
|
|
|
|
model Node {
|
|
id Int @id @default(autoincrement())
|
|
pub_id Bytes @unique
|
|
name String
|
|
platform Int @default(0)
|
|
version String?
|
|
last_seen DateTime @default(now())
|
|
timezone String?
|
|
date_created DateTime @default(now())
|
|
|
|
sync_events SyncEvent[]
|
|
jobs Job[]
|
|
|
|
Location Location[]
|
|
|
|
@@map("node")
|
|
}
|
|
|
|
model Volume {
|
|
id Int @id @default(autoincrement())
|
|
node_id Int
|
|
name String
|
|
mount_point String
|
|
total_bytes_capacity String @default("0")
|
|
total_bytes_available String @default("0")
|
|
disk_type String?
|
|
filesystem String?
|
|
is_system Boolean @default(false)
|
|
date_modified DateTime @default(now())
|
|
|
|
@@unique([node_id, mount_point, name])
|
|
@@map("volume")
|
|
}
|
|
|
|
model Location {
|
|
id Int @id @default(autoincrement())
|
|
pub_id Bytes @unique
|
|
node_id Int
|
|
name String?
|
|
local_path String?
|
|
total_capacity Int?
|
|
available_capacity Int?
|
|
filesystem String?
|
|
disk_type Int?
|
|
is_removable Boolean?
|
|
is_online Boolean @default(true)
|
|
is_archived Boolean @default(false)
|
|
date_created DateTime @default(now())
|
|
|
|
node Node @relation(fields: [node_id], references: [id])
|
|
file_paths FilePath[]
|
|
indexer_rules IndexerRulesInLocation[]
|
|
|
|
@@map("location")
|
|
}
|
|
|
|
model Object {
|
|
id Int @id @default(autoincrement())
|
|
// content addressable storage id - sha256 sampled checksum
|
|
cas_id String @unique
|
|
// full byte contents digested into sha256 checksum
|
|
integrity_checksum String? @unique
|
|
// basic metadata
|
|
name String?
|
|
extension String?
|
|
kind Int @default(0)
|
|
size_in_bytes String
|
|
key_id Int?
|
|
// handy ways to mark an object
|
|
hidden Boolean @default(false)
|
|
favorite Boolean @default(false)
|
|
important Boolean @default(false)
|
|
// if we have generated preview media for this object
|
|
has_thumbnail Boolean @default(false)
|
|
has_thumbstrip Boolean @default(false)
|
|
has_video_preview Boolean @default(false)
|
|
// integration with ipfs
|
|
ipfs_id String?
|
|
// plain text note
|
|
note String?
|
|
// the original known creation date of this object
|
|
date_created DateTime @default(now())
|
|
// the last time this object was modified
|
|
date_modified DateTime @default(now())
|
|
// when this object was first indexed
|
|
date_indexed DateTime @default(now())
|
|
|
|
tags TagOnObject[]
|
|
labels LabelOnObject[]
|
|
albums ObjectInAlbum[]
|
|
spaces ObjectInSpace[]
|
|
file_paths FilePath[]
|
|
comments Comment[]
|
|
media_data MediaData?
|
|
|
|
key Key? @relation(fields: [key_id], references: [id])
|
|
|
|
@@map("object")
|
|
}
|
|
|
|
model FilePath {
|
|
id Int
|
|
is_dir Boolean @default(false)
|
|
// location that owns this path
|
|
location_id Int
|
|
// a path generated from local file_path ids eg: "34/45/67/890"
|
|
materialized_path String
|
|
// the name and extension
|
|
name String
|
|
extension String?
|
|
// the unique Object for this file path
|
|
object_id Int?
|
|
// the parent in the file tree
|
|
parent_id Int?
|
|
key_id Int? // replacement for encryption
|
|
// permissions String?
|
|
// temp_cas_id String? // so a filepath can be created without its File, as they're created lazily
|
|
|
|
date_created DateTime @default(now())
|
|
date_modified DateTime @default(now())
|
|
date_indexed DateTime @default(now())
|
|
|
|
object Object? @relation(fields: [object_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
|
location Location? @relation(fields: [location_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
|
|
|
// NOTE: this self relation for the file tree was causing SQLite to go to forever bed, disabling until workaround
|
|
// parent FilePath? @relation("directory_file_paths", fields: [parent_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
// children FilePath[] @relation("directory_file_paths")
|
|
|
|
key Key? @relation(fields: [key_id], references: [id])
|
|
|
|
@@id([location_id, id])
|
|
@@unique([location_id, materialized_path, name, extension])
|
|
@@index([location_id])
|
|
@@map("file_path")
|
|
}
|
|
|
|
// if there is a conflicting cas_id, the conficting file should be updated to have a larger cas_id as the field is unique, however this record is kept to tell the indexer (upon discovering this CAS) that there is alternate versions of the file and to check by a full integrity hash to define for which to associate with.
|
|
model FileConflict {
|
|
original_object_id Int @unique
|
|
detactched_object_id Int @unique
|
|
|
|
@@map("file_conflict")
|
|
}
|
|
|
|
// keys allow us to know exactly which files can be decrypted with a given key
|
|
// they can be "mounted" to a client, and then used to decrypt files automatically
|
|
model Key {
|
|
id Int @id @default(autoincrement())
|
|
// used to identify the key when it is entered by user
|
|
checksum String @unique
|
|
name String?
|
|
// nullable if concealed for security
|
|
date_created DateTime? @default(now())
|
|
// so we know which algorithm to use, can be null if user must select
|
|
algorithm Int? @default(0)
|
|
|
|
objects Object[]
|
|
file_paths FilePath[]
|
|
|
|
@@map("key")
|
|
}
|
|
|
|
model MediaData {
|
|
id Int @id
|
|
pixel_width Int?
|
|
pixel_height Int?
|
|
longitude Float?
|
|
latitude Float?
|
|
fps Int?
|
|
capture_device_make String? // eg: "Apple"
|
|
capture_device_model String? // eg: "iPhone 12"
|
|
capture_device_software String? // eg: "12.1.1"
|
|
duration_seconds Int?
|
|
codecs String? // eg: "h264,acc"
|
|
streams Int?
|
|
|
|
// change this relation to Object after testing
|
|
objects Object? @relation(fields: [id], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
|
|
|
@@map("media_data")
|
|
}
|
|
|
|
model Tag {
|
|
id Int @id @default(autoincrement())
|
|
pub_id Bytes @unique
|
|
name String?
|
|
color String?
|
|
total_objects Int? @default(0)
|
|
redundancy_goal Int? @default(1)
|
|
date_created DateTime @default(now())
|
|
date_modified DateTime @default(now())
|
|
|
|
tag_objects TagOnObject[]
|
|
|
|
@@map("tag")
|
|
}
|
|
|
|
model TagOnObject {
|
|
date_created DateTime @default(now())
|
|
|
|
tag_id Int
|
|
tag Tag @relation(fields: [tag_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
object_id Int
|
|
object Object @relation(fields: [object_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
@@id([tag_id, object_id])
|
|
@@map("tag_on_object")
|
|
}
|
|
|
|
model Label {
|
|
id Int @id @default(autoincrement())
|
|
pub_id Bytes @unique
|
|
name String?
|
|
date_created DateTime @default(now())
|
|
date_modified DateTime @default(now())
|
|
|
|
label_objects LabelOnObject[]
|
|
|
|
@@map("label")
|
|
}
|
|
|
|
model LabelOnObject {
|
|
date_created DateTime @default(now())
|
|
|
|
label_id Int
|
|
label Label @relation(fields: [label_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
object_id Int
|
|
object Object @relation(fields: [object_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
@@id([label_id, object_id])
|
|
@@map("label_on_object")
|
|
}
|
|
|
|
model Space {
|
|
id Int @id @default(autoincrement())
|
|
pub_id Bytes @unique
|
|
name String?
|
|
description String?
|
|
date_created DateTime @default(now())
|
|
date_modified DateTime @default(now())
|
|
|
|
objects ObjectInSpace[]
|
|
|
|
@@map("space")
|
|
}
|
|
|
|
model ObjectInSpace {
|
|
date_created DateTime @default(now())
|
|
|
|
space_id Int
|
|
space Space @relation(fields: [space_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
object_id Int
|
|
object Object @relation(fields: [object_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
@@id([space_id, object_id])
|
|
@@map("object_in_space")
|
|
}
|
|
|
|
model Job {
|
|
id Bytes @id
|
|
name String
|
|
node_id Int
|
|
action Int
|
|
status Int @default(0)
|
|
data Bytes?
|
|
metadata Bytes?
|
|
|
|
task_count Int @default(1)
|
|
completed_task_count Int @default(0)
|
|
date_created DateTime @default(now())
|
|
date_modified DateTime @default(now())
|
|
seconds_elapsed Int @default(0)
|
|
|
|
nodes Node @relation(fields: [node_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
|
|
|
@@map("job")
|
|
}
|
|
|
|
model Album {
|
|
id Int @id @default(autoincrement())
|
|
pub_id Bytes @unique
|
|
name String
|
|
is_hidden Boolean @default(false)
|
|
|
|
date_created DateTime @default(now())
|
|
date_modified DateTime @default(now())
|
|
|
|
objects ObjectInAlbum[]
|
|
|
|
@@map("album")
|
|
}
|
|
|
|
model ObjectInAlbum {
|
|
date_created DateTime @default(now())
|
|
|
|
album_id Int
|
|
album Album @relation(fields: [album_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
object_id Int
|
|
object Object @relation(fields: [object_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
@@id([album_id, object_id])
|
|
@@map("object_in_album")
|
|
}
|
|
|
|
model Comment {
|
|
id Int @id @default(autoincrement())
|
|
pub_id Bytes @unique
|
|
content String
|
|
date_created DateTime @default(now())
|
|
date_modified DateTime @default(now())
|
|
object_id Int?
|
|
object Object? @relation(fields: [object_id], references: [id])
|
|
|
|
@@map("comment")
|
|
}
|
|
|
|
model IndexerRule {
|
|
id Int @id @default(autoincrement())
|
|
kind Int
|
|
name String
|
|
parameters Bytes
|
|
date_created DateTime @default(now())
|
|
date_modified DateTime @default(now())
|
|
|
|
locations IndexerRulesInLocation[]
|
|
|
|
@@map("indexer_rule")
|
|
}
|
|
|
|
model IndexerRulesInLocation {
|
|
date_created DateTime @default(now())
|
|
|
|
location_id Int
|
|
location Location @relation(fields: [location_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
indexer_rule_id Int
|
|
indexer_rule IndexerRule @relation(fields: [indexer_rule_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
|
|
|
@@id([location_id, indexer_rule_id])
|
|
@@map("indexer_rule_in_location")
|
|
}
|