all queries for tags

This commit is contained in:
Brandon Thomas committed 2024-10-02 02:32:20 -04:00
1 parent aec5675784
commit 606a439352
6 files changed
+146 -6

No files matched your search

@@ -0,0 +1,36 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n t.token as `token: tokens::tokens::tags::TagToken`,\n t.tag_value\n\nFROM\n tags AS t\nJOIN tag_uses AS u\n ON t.token = u.tag_token\nWHERE\n u.entity_type = ?\n AND u.entity_token = ?\n AND u.maybe_deleted_at IS NULL\nORDER BY t.id DESC\nLIMIT 500\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::tags::TagToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "tag_value",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
false
]
},
"hash": "3929e9fe74e75fad7252681880c6c3bd7e76e96b0bf603f77f6a9b2d4fcda18d"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO tags\nSET\n token = ?,\n tag_value = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "c7e848e4c906a34ac5a4ad8cc73354baa8d5cd81170dd06d66d7f414505d538b"
}
@@ -4,7 +4,7 @@ use tokens::tokens::tags::TagToken;
use crate::utils::transactor::Transactor;
pub struct Tag {
pub struct EntityTag {
pub token: TagToken,
pub tag_value: String,
}
@@ -12,7 +12,7 @@ pub struct Tag {
pub async fn list_tags_for_entity(
tag_entity: TagUseEntity,
transactor: Transactor<'_, '_>,
) -> AnyhowResult<Vec<Tag>> {
) -> AnyhowResult<Vec<EntityTag>> {
let (entity_type, entity_token) = tag_entity.get_composite_keys();
@@ -51,7 +51,7 @@ LIMIT 500
};
Ok(results.into_iter()
.map(|record| Tag {
.map(|record| EntityTag {
token: record.token,
tag_value: record.tag_value,
})
@@ -1,3 +1,4 @@
pub mod list_tags_for_entity;
pub mod create_tag;
pub mod update_tags_for_entity;
pub mod update_tags_for_entity;
mod select_matching_tags;
@@ -0,0 +1,79 @@
use crate::utils::transactor::Transactor;
use errors::AnyhowResult;
use sqlx::mysql::MySqlRow;
use sqlx::{FromRow, MySql, QueryBuilder, Row};
use tokens::tokens::tags::TagToken;
pub struct MatchingTag {
pub token: TagToken,
pub tag_value: String,
}
pub async fn list_tags_for_entity(
tag_values: &[&str],
transactor: Transactor<'_, '_>,
) -> AnyhowResult<Vec<MatchingTag>> {
if tag_values.is_empty() {
return Ok(Vec::new()) // This prevents a SQL error when the IN clause is empty.
}
let tag_values = tag_values.iter()
.map(|tag| tag.trim().to_lowercase())
.collect::<Vec<_>>();
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new(
r#"
SELECT
t.token as `token: tokens::tokens::tags::TagToken`,
t.tag_value
FROM
tags AS t
WHERE
t.tag_value IN (
"#,
);
let mut separated = query_builder.separated(", ");
for tag_value in tag_values.iter() {
separated.push_bind(tag_value);
}
separated.push_unseparated(") ");
let query = query_builder.build_query_as::<RawTag>();
let results = match transactor {
Transactor::Pool { pool } => {
query.fetch_all(pool).await?
},
Transactor::Connection { connection } => {
query.fetch_all(connection).await?
},
Transactor::Transaction { transaction } => {
query.fetch_all(&mut **transaction).await?
},
};
Ok(results.into_iter()
.map(|record| MatchingTag {
token: record.token,
tag_value: record.tag_value,
})
.collect())
}
struct RawTag {
token: TagToken,
tag_value: String,
}
impl FromRow<'_, MySqlRow> for RawTag {
fn from_row(row: &MySqlRow) -> Result<Self, sqlx::Error> {
Ok(Self {
token: TagToken::new(row.try_get("token")?),
tag_value: row.try_get("tag_value")?,
})
}
}
@@ -1,8 +1,19 @@
use composite_identifiers::by_table::tag_uses::tag_use_entity::TagUseEntity;
use errors::AnyhowResult;
use sqlx::pool::PoolConnection;
use sqlx::{Acquire, Executor, MySql, QueryBuilder, Transaction};
use sqlx::{Acquire, Executor, FromRow, MySql, QueryBuilder, Transaction};
use sqlx::mysql::MySqlRow;
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory;
use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginModelType;
use enums::by_table::media_files::media_file_origin_product_category::MediaFileOriginProductCategory;
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::common::visibility::Visibility;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::tags::TagToken;
use crate::queries::beta_keys::get_beta_key_by_value::RawRecord;
pub async fn update_tags_for_entity(
entity: TagUseEntity,
@@ -59,7 +70,8 @@ async fn insert_query(
tags: &[TagToken],
transaction: &mut Transaction<'_, MySql>,
) -> AnyhowResult<()> {
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new("INSERT INTO tag_uses ");
// NB: Insert ignore will insert non-duplicate rows and silently ignore duplicates
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new("INSERT IGNORE INTO tag_uses ");
query_builder.push(" (entity_type, entity_token, tag_token) VALUES ");