init
This commit is contained in:
@@ -658,6 +658,7 @@ impl MigrationTrait for Migration {
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Alias::new("server_id")).uuid().null())
|
||||
.col(ColumnDef::new(Alias::new("name")).string().not_null())
|
||||
.col(ColumnDef::new(Alias::new("emoji_type")).string().not_null())
|
||||
.col(ColumnDef::new(Alias::new("unicode_sequence")).text().null())
|
||||
.col(ColumnDef::new(Alias::new("file_path")).text().null())
|
||||
@@ -705,56 +706,6 @@ impl MigrationTrait for Migration {
|
||||
|
||||
seed_unicode_emojis(manager).await?;
|
||||
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Alias::new("emoji_alias"))
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("id"))
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Alias::new("emoji_id")).uuid().not_null())
|
||||
.col(ColumnDef::new(Alias::new("alias")).string().not_null())
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("created_at"))
|
||||
.timestamp_with_time_zone()
|
||||
.not_null()
|
||||
.default(Expr::current_timestamp()),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("updated_at"))
|
||||
.timestamp_with_time_zone()
|
||||
.not_null()
|
||||
.default(Expr::current_timestamp()),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_emoji_alias_emoji")
|
||||
.from(Alias::new("emoji_alias"), Alias::new("emoji_id"))
|
||||
.to(Alias::new("emoji"), Alias::new("id"))
|
||||
.on_delete(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.name("uq_emoji_alias_emoji")
|
||||
.table(Alias::new("emoji_alias"))
|
||||
.col(Alias::new("emoji_id"))
|
||||
.col(Alias::new("alias"))
|
||||
.unique()
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
seed_unicode_aliases(manager).await?;
|
||||
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
@@ -1019,7 +970,6 @@ impl MigrationTrait for Migration {
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
let tables = [
|
||||
"computed_permission",
|
||||
"emoji_alias",
|
||||
"emoji",
|
||||
"channel_user_read_state",
|
||||
"channel_user_permission",
|
||||
@@ -1060,21 +1010,42 @@ impl MigrationTrait for Migration {
|
||||
/// number of bind parameters in a single statement to 999.
|
||||
async fn seed_unicode_emojis(manager: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
const CHUNK_SIZE: usize = 250;
|
||||
let rows = unicode_rows()?;
|
||||
let mut used_names = HashSet::with_capacity(3944);
|
||||
let rows = unicode_rows()?
|
||||
.into_iter()
|
||||
.map(|(id, sequence, raw_name)| {
|
||||
let base = normalize_unicode_name(&raw_name);
|
||||
let mut name = base.clone();
|
||||
if !used_names.insert(name.clone()) {
|
||||
name = format!("{base}_u{}", sequence.replace(' ', ""));
|
||||
if name.len() > 64 {
|
||||
name.truncate(64);
|
||||
}
|
||||
if !used_names.insert(name.clone()) {
|
||||
return Err(DbErr::Custom(format!(
|
||||
"duplicate generated emoji name: {name}"
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok((id, sequence, name))
|
||||
})
|
||||
.collect::<Result<Vec<_>, DbErr>>()?;
|
||||
|
||||
for chunk in rows.chunks(CHUNK_SIZE) {
|
||||
let mut insert = Query::insert();
|
||||
insert.into_table(Alias::new("emoji")).columns([
|
||||
Alias::new("id"),
|
||||
Alias::new("server_id"),
|
||||
Alias::new("name"),
|
||||
Alias::new("emoji_type"),
|
||||
Alias::new("unicode_sequence"),
|
||||
]);
|
||||
|
||||
for (id, sequence, _) in chunk {
|
||||
for (id, sequence, name) in chunk {
|
||||
insert.values_panic([
|
||||
Expr::val(*id).into(),
|
||||
Expr::val(Option::<Uuid>::None).into(),
|
||||
Expr::val(name.as_str()).into(),
|
||||
Expr::val("unicode").into(),
|
||||
Expr::val(sequence.as_str()).into(),
|
||||
]);
|
||||
@@ -1086,61 +1057,6 @@ async fn seed_unicode_emojis(manager: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn seed_unicode_aliases(manager: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
const CHUNK_SIZE: usize = 250;
|
||||
let rows = unicode_rows()?;
|
||||
let mut aliases = Vec::with_capacity(rows.len());
|
||||
let mut used = HashSet::with_capacity(rows.len());
|
||||
|
||||
for (_, sequence, name) in rows {
|
||||
let base = normalize_unicode_alias(&name);
|
||||
let mut alias = base.clone();
|
||||
if !used.insert(alias.clone()) {
|
||||
alias = format!("{base}_u{}", sequence.replace(' ', ""));
|
||||
if alias.len() > 64 {
|
||||
alias.truncate(64);
|
||||
}
|
||||
if !used.insert(alias.clone()) {
|
||||
return Err(DbErr::Custom(format!(
|
||||
"duplicate generated emoji alias: {alias}"
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
let emoji_id = Uuid::new_v5(
|
||||
&Uuid::NAMESPACE_URL,
|
||||
format!("https://oxspeak.local/unicode/{UNICODE_EMOJI_VERSION}/{sequence}").as_bytes(),
|
||||
);
|
||||
let id = Uuid::new_v5(
|
||||
&Uuid::NAMESPACE_URL,
|
||||
format!("https://oxspeak.local/unicode-alias/{UNICODE_EMOJI_VERSION}/{sequence}")
|
||||
.as_bytes(),
|
||||
);
|
||||
aliases.push((id, emoji_id, alias));
|
||||
}
|
||||
|
||||
for chunk in aliases.chunks(CHUNK_SIZE) {
|
||||
let mut insert = Query::insert();
|
||||
insert.into_table(Alias::new("emoji_alias")).columns([
|
||||
Alias::new("id"),
|
||||
Alias::new("emoji_id"),
|
||||
Alias::new("alias"),
|
||||
]);
|
||||
|
||||
for (id, emoji_id, alias) in chunk {
|
||||
insert.values_panic([
|
||||
Expr::val(*id).into(),
|
||||
Expr::val(*emoji_id).into(),
|
||||
Expr::val(alias.as_str()).into(),
|
||||
]);
|
||||
}
|
||||
|
||||
manager.exec_stmt(insert).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unicode_rows() -> Result<Vec<(Uuid, String, String)>, DbErr> {
|
||||
UNICODE_EMOJI_DATA
|
||||
.lines()
|
||||
@@ -1160,7 +1076,7 @@ fn unicode_rows() -> Result<Vec<(Uuid, String, String)>, DbErr> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn normalize_unicode_alias(name: &str) -> String {
|
||||
fn normalize_unicode_name(name: &str) -> String {
|
||||
let mut alias = String::with_capacity(name.len());
|
||||
let mut separator = false;
|
||||
|
||||
@@ -1223,16 +1139,16 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unicode_aliases_are_normalized_for_the_existing_api_constraints() {
|
||||
fn unicode_names_are_normalized_for_the_existing_api_constraints() {
|
||||
assert_eq!(
|
||||
normalize_unicode_alias("flag: United States"),
|
||||
normalize_unicode_name("flag: United States"),
|
||||
"flag_united_states"
|
||||
);
|
||||
assert_eq!(
|
||||
normalize_unicode_alias("thumbs up: medium skin tone"),
|
||||
normalize_unicode_name("thumbs up: medium skin tone"),
|
||||
"thumbs_up_medium_skin_tone"
|
||||
);
|
||||
assert!(normalize_unicode_alias("woman technologist")
|
||||
assert!(normalize_unicode_name("woman technologist")
|
||||
.chars()
|
||||
.all(|character| character.is_ascii_alphanumeric() || character == '_'));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user