mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-27 12:10:08 -04:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4812e5e3e | ||
|
|
a8ac030d24 | ||
|
|
9249a6274d |
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE prompts DROP COLUMN maybe_model_type;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE prompts
|
||||
ADD COLUMN maybe_model_type VARCHAR(32) DEFAULT NULL;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE prompts DROP COLUMN maybe_generation_provider;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE prompts
|
||||
ADD COLUMN maybe_generation_provider VARCHAR(16) DEFAULT NULL;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE prompts DROP COLUMN maybe_anonymous_visitor_token;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE prompts
|
||||
ADD COLUMN maybe_anonymous_visitor_token VARCHAR(32) DEFAULT NULL;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
DROP TABLE prompt_context_items;
|
||||
@@ -0,0 +1,30 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- An n:m join table between prompts and media_files.
|
||||
-- This associates mostly image media files with prompts, though we could conceivably
|
||||
-- also store 3D sets, etc.
|
||||
CREATE TABLE prompt_context_items (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- The semantic type of context.
|
||||
context_semantic_type VARCHAR(16) NOT NULL,
|
||||
|
||||
-- Foreign key, many-to-many
|
||||
-- There is no uniqueness constraint for (prompt_token, media_token) because a user
|
||||
-- might attach many duplicate images to the same prompt.
|
||||
prompt_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Foreign key to the media token
|
||||
-- There is no uniqueness constraint for (prompt_token, media_token) because a user
|
||||
-- might attach many duplicate images to the same prompt.
|
||||
media_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
KEY index_prompt_token (prompt_token),
|
||||
KEY index_media_token (media_token)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -61,6 +61,8 @@ CREATE TABLE media_files (
|
||||
-- * 'workflow' (DEPRECATED)
|
||||
origin_product_category VARCHAR(16) NOT NULL DEFAULT "unknown",
|
||||
|
||||
-- TODO(bt,2025-07-23): needs maybe_generation_provider.
|
||||
|
||||
-- For inference that can be tied back to a model, the type of model.
|
||||
-- There are multiple indices on this column!
|
||||
-- DO NOT EXPOSE THIS TO USERS VIA THE API, as we may leak secrets in doing so.
|
||||
|
||||
@@ -19,13 +19,25 @@ CREATE TABLE prompts (
|
||||
-- Original product to which the prompt applied.
|
||||
-- Prompts may or may not be compatible across products.
|
||||
-- Possible values:
|
||||
-- * 'stable_diffusion'
|
||||
-- * 'comfy_ui'
|
||||
-- * 'stable_diffusion' (legacy)
|
||||
-- * 'comfy_ui' (legacy)
|
||||
-- * 'artcraft_app'
|
||||
prompt_type VARCHAR(16) NOT NULL,
|
||||
|
||||
-- Whomever created the prompt
|
||||
-- What type of model was used to generate the result.
|
||||
-- NB: We're conflating prompts with outputs, but in a
|
||||
-- sense the model is inextricably part of the prompt.
|
||||
maybe_model_type VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- What service provided the generation.
|
||||
maybe_generation_provider VARCHAR(16) NOT NULL,
|
||||
|
||||
-- Whoever created the prompt
|
||||
maybe_creator_user_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- Whoever created the prompt (anonymous user tracking)
|
||||
maybe_anonymous_visitor_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- ========== PROMPT DETAILS ==========
|
||||
|
||||
-- The positive prompt (optional)
|
||||
|
||||
@@ -259,7 +259,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn serialized_length_ok_for_database() {
|
||||
const MAX_LENGTH : usize = 32;
|
||||
// NB: The media_files table has allocated width for VARCHAR(32), but let's slim it down to 24.
|
||||
const MAX_LENGTH : usize = 24;
|
||||
for variant in MediaFileOriginModelType::all_variants() {
|
||||
let serialized = variant.to_str();
|
||||
assert!(serialized.len() > 0, "variant {:?} is too short", variant);
|
||||
|
||||
@@ -6,6 +6,8 @@ use strum::EnumCount;
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// NB: This will be used by a variety of tables (MySQL and sqlite)!
|
||||
/// Keep the max length to 16 characters.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
@@ -108,5 +110,15 @@ mod tests {
|
||||
assert_eq!(variant, GenerationProvider::from_str(&format!("{:?}", variant)).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialized_length_ok_for_database() {
|
||||
const MAX_LENGTH : usize = 16;
|
||||
for variant in GenerationProvider::all_variants() {
|
||||
let serialized = variant.to_str();
|
||||
assert!(serialized.len() > 0, "variant {:?} is too short", variant);
|
||||
assert!(serialized.len() <= MAX_LENGTH, "variant {:?} is too long", variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod generation_provider;
|
||||
pub mod job_status;
|
||||
pub mod job_status_plus;
|
||||
pub mod model_type;
|
||||
pub mod sqlite;
|
||||
pub mod view_as;
|
||||
pub mod visibility;
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// NB: This will be used by a variety of tables (MySQL and sqlite)!
|
||||
/// Keep the max length to 24 characters.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ModelType {
|
||||
Artcraft,
|
||||
Fal,
|
||||
Sora,
|
||||
}
|
||||
|
||||
impl_enum_display_and_debug_using_to_str!(ModelType);
|
||||
impl_mysql_enum_coders!(ModelType);
|
||||
impl_mysql_from_row!(ModelType);
|
||||
|
||||
// NB: We can derive `sqlx::Type` instead of using `impl_mysql_enum_coders`
|
||||
|
||||
impl ModelType {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Artcraft => "artcraft",
|
||||
Self::Fal => "fal",
|
||||
Self::Sora => "sora",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(job_status: &str) -> Result<Self, String> {
|
||||
match job_status {
|
||||
"artcraft" => Ok(Self::Artcraft),
|
||||
"fal" => Ok(Self::Fal),
|
||||
"sora" => Ok(Self::Sora),
|
||||
_ => Err(format!("invalid task_state: {:?}", job_status)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn all_variants() -> BTreeSet<Self> {
|
||||
// NB: BTreeSet is sorted
|
||||
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
|
||||
BTreeSet::from([
|
||||
Self::Artcraft,
|
||||
Self::Fal,
|
||||
Self::Sora,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::common::model_type::ModelType;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
|
||||
mod explicit_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
assert_serialization(ModelType::Artcraft, "artcraft");
|
||||
assert_serialization(ModelType::Fal, "fal");
|
||||
assert_serialization(ModelType::Sora, "sora");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_str() {
|
||||
assert_eq!(ModelType::Artcraft.to_str(), "artcraft");
|
||||
assert_eq!(ModelType::Fal.to_str(), "fal");
|
||||
assert_eq!(ModelType::Sora.to_str(), "sora");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(ModelType::from_str("artcraft").unwrap(), ModelType::Artcraft);
|
||||
assert_eq!(ModelType::from_str("fal").unwrap(), ModelType::Fal);
|
||||
assert_eq!(ModelType::from_str("sora").unwrap(), ModelType::Sora);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = ModelType::all_variants();
|
||||
assert_eq!(variants.len(), 3);
|
||||
assert_eq!(variants.pop_first(), Some(ModelType::Artcraft));
|
||||
assert_eq!(variants.pop_first(), Some(ModelType::Fal));
|
||||
assert_eq!(variants.pop_first(), Some(ModelType::Sora));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
}
|
||||
}
|
||||
|
||||
mod mechanical_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn variant_length() {
|
||||
use strum::IntoEnumIterator;
|
||||
assert_eq!(ModelType::all_variants().len(), ModelType::iter().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trip() {
|
||||
for variant in ModelType::all_variants() {
|
||||
// Test to_str(), from_str(), Display, and Debug.
|
||||
assert_eq!(variant, ModelType::from_str(variant.to_str()).unwrap());
|
||||
assert_eq!(variant, ModelType::from_str(&format!("{}", variant)).unwrap());
|
||||
assert_eq!(variant, ModelType::from_str(&format!("{:?}", variant)).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialized_length_ok_for_database() {
|
||||
const MAX_LENGTH : usize = 24;
|
||||
for variant in ModelType::all_variants() {
|
||||
let serialized = variant.to_str();
|
||||
assert!(serialized.len() > 0, "variant {:?} is too short", variant);
|
||||
assert!(serialized.len() <= MAX_LENGTH, "variant {:?} is too long", variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user