Store languages directly in database

This commit is contained in:
Felix Ableitner 2022-06-21 15:57:32 +02:00
parent ec1271c423
commit 9bf41100f8
14 changed files with 270 additions and 170 deletions

100
Cargo.lock generated
View file

@ -302,15 +302,6 @@ dependencies = [
"syn 1.0.98",
]
[[package]]
name = "addr2line"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
@ -484,21 +475,6 @@ dependencies = [
"uuid",
]
[[package]]
name = "backtrace"
version = "0.3.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide 0.5.1",
"object",
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.13.0"
@ -1269,28 +1245,6 @@ version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
[[package]]
name = "failure"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
dependencies = [
"backtrace",
"failure_derive",
]
[[package]]
name = "failure_derive"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
"proc-macro2 1.0.40",
"quote 1.0.20",
"syn 1.0.98",
"synstructure",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
@ -1516,12 +1470,6 @@ dependencies = [
"wasi 0.10.0+wasi-snapshot-preview1",
]
[[package]]
name = "gimli"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
[[package]]
name = "h2"
version = "0.3.12"
@ -1844,16 +1792,6 @@ version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35e70ee094dc02fd9c13fdad4940090f22dbd6ac7c9e7094a46cf0232a50bc7c"
[[package]]
name = "iso639-1"
version = "0.3.0"
source = "git+https://github.com/Nutomic/iso639.git?branch=add-strum#bf2fd77f3b3dd1492c76c0c1e289d21843436980"
dependencies = [
"failure",
"strum",
"strum_macros",
]
[[package]]
name = "itertools"
version = "0.10.3"
@ -2048,7 +1986,6 @@ dependencies = [
"diesel",
"diesel-derive-newtype",
"diesel_migrations",
"iso639-1",
"lemmy_utils",
"once_cell",
"regex",
@ -2597,15 +2534,6 @@ dependencies = [
"libc",
]
[[package]]
name = "object"
version = "0.28.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.12.0"
@ -2999,7 +2927,7 @@ version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
dependencies = [
"unicode-xid 0.1.0",
"unicode-xid",
]
[[package]]
@ -3417,12 +3345,6 @@ dependencies = [
"quick-xml",
]
[[package]]
name = "rustc-demangle"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
name = "rustc_version"
version = "0.4.0"
@ -3811,7 +3733,7 @@ checksum = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
dependencies = [
"proc-macro2 0.4.30",
"quote 0.6.13",
"unicode-xid 0.1.0",
"unicode-xid",
]
[[package]]
@ -3825,18 +3747,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "synstructure"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [
"proc-macro2 1.0.40",
"quote 1.0.20",
"syn 1.0.98",
"unicode-xid 0.2.2",
]
[[package]]
name = "tap"
version = "1.0.1"
@ -4345,12 +4255,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "unicode_categories"
version = "0.1.1"

View file

@ -22,7 +22,6 @@ serde = { version = "1.0.136", features = ["derive"] }
url = { version = "2.2.2", features = ["serde"] }
strum = "0.24.0"
strum_macros = "0.24.0"
iso639-1 = { git = "https://github.com/Nutomic/iso639.git", branch = "add-strum", features = ["strum"] }
serde_json = { version = "1.0.79", features = ["preserve_order"], optional = true }
activitypub_federation = { version = "0.2.0", optional = true }
lemmy_utils = { version = "=0.16.5", path = "../utils", optional = true }

View file

@ -0,0 +1,31 @@
use crate::source::language::Language;
use diesel::{result::Error, PgConnection, RunQueryDsl};
impl Language {
pub fn read_all(conn: &PgConnection) -> Result<Vec<Language>, Error> {
use crate::schema::language::dsl::*;
language.load::<Self>(conn)
}
pub fn read_from_code(code_: &str, conn: &PgConnection) -> Result<Language, Error> {
use crate::schema::language::dsl::*;
language.find(code.eq(code_)).load::<Self>(conn)
}
}
#[cfg(test)]
mod tests {
use crate::{source::language::Language, utils::establish_unpooled_connection};
use serial_test::serial;
#[test]
#[serial]
fn test_languages() {
let conn = establish_unpooled_connection();
let all = Language::read_all(&conn).unwrap();
assert_eq!(123, all.len());
assert_eq!("xy", all[5].code);
}
}

View file

@ -4,6 +4,7 @@ pub mod comment_report;
pub mod community;
pub mod community_block;
pub mod email_verification;
pub mod language;
pub mod local_user;
pub mod moderator;
pub mod password_reset_request;

View file

@ -1,11 +1,9 @@
use iso639_1::Iso639_1;
use serde::{Deserialize, Serialize};
use std::{
fmt,
fmt::{Display, Formatter},
ops::Deref,
};
use strum::IntoEnumIterator;
use url::Url;
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
@ -70,6 +68,10 @@ pub struct CommentReportId(i32);
#[cfg_attr(feature = "full", derive(DieselNewType))]
pub struct PostReportId(i32);
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)]
#[cfg_attr(feature = "full", derive(DieselNewType))]
pub struct LanguageId(pub i32);
#[repr(transparent)]
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
#[cfg_attr(feature = "full", derive(AsExpression, FromSqlRow))]
@ -103,48 +105,3 @@ impl Deref for DbUrl {
&self.0
}
}
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "full", derive(DieselNewType))]
pub struct LanguageIdentifier(String);
impl LanguageIdentifier {
pub fn new(lang: &str) -> LanguageIdentifier {
// check that language is valid
match Iso639_1::try_from(lang) {
Ok(_) => return LanguageIdentifier(lang.to_string()),
Err(_) => {
// undetermined language (ISO 639-2)
if lang == "und" {
return LanguageIdentifier(lang.to_string());
}
}
}
LanguageIdentifier::default()
}
pub fn into_inner(self) -> String {
self.0
}
/// Returns identifiers for all valid languages (including undefined).
pub fn all_languages() -> Vec<LanguageIdentifier> {
let mut all: Vec<LanguageIdentifier> = Iso639_1::iter()
.map(|i| LanguageIdentifier(i.name().to_string()))
.collect();
all.push(LanguageIdentifier("und".to_string()));
all
}
pub fn is_undetermined(&self) -> bool {
self.0 == "und"
}
}
impl Default for LanguageIdentifier {
fn default() -> LanguageIdentifier {
// default is "undetermined language"
LanguageIdentifier("und".to_string())
}
}

View file

@ -649,6 +649,14 @@ table! {
}
}
table! {
language (id) {
id -> Int4,
code -> Text,
name -> Text,
}
}
joinable!(comment_alias_1 -> person_alias_1 (creator_id));
joinable!(comment -> comment_alias_1 (parent_id));
joinable!(person_mention -> person_alias_1 (recipient_id));
@ -770,5 +778,6 @@ allow_tables_to_appear_in_same_query!(
admin_purge_person,
admin_purge_post,
email_verification,
registration_application
registration_application,
language
);

View file

@ -0,0 +1,11 @@
use crate::newtypes::LanguageId;
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
#[cfg_attr(feature = "full", table_name = "language")]
pub struct Language {
pub id: LanguageId,
pub code: String,
pub name: String,
}

View file

@ -1,4 +1,4 @@
use crate::newtypes::{LanguageIdentifier, LocalUserId, PersonId};
use crate::newtypes::{LanguageId, LocalUserId, PersonId};
use serde::{Deserialize, Serialize};
#[cfg(feature = "full")]
@ -26,7 +26,7 @@ pub struct LocalUser {
pub show_new_post_notifs: bool,
pub email_verified: bool,
pub accepted_application: bool,
pub discussion_languages: Vec<LanguageIdentifier>,
pub discussion_languages: Vec<LanguageId>,
}
// TODO redo these, check table defaults
@ -50,7 +50,7 @@ pub struct LocalUserForm {
pub show_new_post_notifs: Option<bool>,
pub email_verified: Option<bool>,
pub accepted_application: Option<bool>,
pub discussion_languages: Option<Vec<LanguageIdentifier>>,
pub discussion_languages: Option<Vec<LanguageId>>,
}
/// A local user view that removes password encrypted
@ -75,5 +75,5 @@ pub struct LocalUserSettings {
pub show_new_post_notifs: bool,
pub email_verified: bool,
pub accepted_application: bool,
pub discussion_languages: Vec<LanguageIdentifier>,
pub discussion_languages: Vec<LanguageId>,
}

View file

@ -5,6 +5,7 @@ pub mod comment_report;
pub mod community;
pub mod community_block;
pub mod email_verification;
pub mod language;
pub mod local_user;
pub mod moderator;
pub mod password_reset_request;

View file

@ -1,4 +1,4 @@
use crate::newtypes::{CommunityId, DbUrl, LanguageIdentifier, PersonId, PostId};
use crate::newtypes::{CommunityId, DbUrl, LanguageId, PersonId, PostId};
use serde::{Deserialize, Serialize};
#[cfg(feature = "full")]
@ -27,7 +27,7 @@ pub struct Post {
pub thumbnail_url: Option<DbUrl>,
pub ap_id: DbUrl,
pub local: bool,
pub language: LanguageIdentifier,
pub language: LanguageId,
}
#[derive(Default)]
@ -52,7 +52,7 @@ pub struct PostForm {
pub thumbnail_url: Option<DbUrl>,
pub ap_id: Option<DbUrl>,
pub local: Option<bool>,
pub language: Option<LanguageIdentifier>,
pub language: Option<LanguageId>,
}
#[derive(PartialEq, Debug)]

View file

@ -497,6 +497,7 @@ mod tests {
use diesel::PgConnection;
use lemmy_db_schema::{
aggregates::structs::PostAggregates,
newtypes::LanguageIdentifier,
source::{
community::*,
community_block::{CommunityBlock, CommunityBlockForm},
@ -511,7 +512,6 @@ mod tests {
SubscribedType,
};
use serial_test::serial;
use lemmy_db_schema::newtypes::LanguageIdentifier;
struct Data {
inserted_person: Person,
@ -844,14 +844,8 @@ mod tests {
let expected_post_listing = expected_post_listing(&data, &conn);
assert_eq!(
1,
read_post_listing_french.len()
);
assert_eq!(
expected_post_listing,
read_post_listing_french[0]
);
assert_eq!(1, read_post_listing_french.len());
assert_eq!(expected_post_listing, read_post_listing_french[0]);
cleanup(data, &conn);
}

View file

@ -1,4 +0,0 @@
alter table local_user rename column lang to interface_language;
alter table local_user add column discussion_languages varchar(3)[] not null default '{}';
alter table post add column language varchar(3) not null default 'und';

View file

@ -1,3 +1,5 @@
drop table all_languages;
alter table local_user rename column interface_language to lang;
alter table local_user drop column discussion_languages;

View file

@ -0,0 +1,195 @@
create table language (
id serial primary key,
code varchar(3),
name text
);
alter table local_user rename column lang to interface_language;
alter table local_user add column discussion_languages integer[] not null default '{}';
alter table post add column language integer not null default 0;
insert into language(id, code, name) values (0, 'und', 'Undetermined');
insert into language(code, name) values ('aa', 'Afaraf');
insert into language(code, name) values ('ab', 'аҧсуа бызшәа');
insert into language(code, name) values ('ae', 'avesta');
insert into language(code, name) values ('af', 'Afrikaans');
insert into language(code, name) values ('ak', 'Akan');
insert into language(code, name) values ('am', 'አማርኛ');
insert into language(code, name) values ('an', 'aragonés');
insert into language(code, name) values ('ar', 'اَلْعَرَبِيَّةُ');
insert into language(code, name) values ('as', 'অসমীয়া');
insert into language(code, name) values ('av', 'авар мацӀ');
insert into language(code, name) values ('ay', 'aymar aru');
insert into language(code, name) values ('az', 'azərbaycan dili');
insert into language(code, name) values ('ba', 'башҡорт теле');
insert into language(code, name) values ('be', 'беларуская мова');
insert into language(code, name) values ('bg', 'български език');
insert into language(code, name) values ('bi', 'Bislama');
insert into language(code, name) values ('bm', 'bamanankan');
insert into language(code, name) values ('bn', 'বাংলা');
insert into language(code, name) values ('bo', 'བོད་ཡིག');
insert into language(code, name) values ('br', 'brezhoneg');
insert into language(code, name) values ('bs', 'bosanski jezik');
insert into language(code, name) values ('ca', 'Català');
insert into language(code, name) values ('ce', 'нохчийн мотт');
insert into language(code, name) values ('ch', 'Chamoru');
insert into language(code, name) values ('co', 'corsu');
insert into language(code, name) values ('cr', 'ᓀᐦᐃᔭᐍᐏᐣ');
insert into language(code, name) values ('cs', 'čeština');
insert into language(code, name) values ('cu', 'ѩзыкъ словѣньскъ');
insert into language(code, name) values ('cv', 'чӑваш чӗлхи');
insert into language(code, name) values ('cy', 'Cymraeg');
insert into language(code, name) values ('da', 'dansk');
insert into language(code, name) values ('de', 'Deutsch');
insert into language(code, name) values ('dv', 'ދިވެހި');
insert into language(code, name) values ('dz', 'རྫོང་ཁ');
insert into language(code, name) values ('ee', 'Eʋegbe');
insert into language(code, name) values ('el', 'Ελληνικά');
insert into language(code, name) values ('en', 'English');
insert into language(code, name) values ('eo', 'Esperanto');
insert into language(code, name) values ('es', 'Español');
insert into language(code, name) values ('et', 'eesti');
insert into language(code, name) values ('eu', 'euskara');
insert into language(code, name) values ('fa', 'فارسی');
insert into language(code, name) values ('ff', 'Fulfulde');
insert into language(code, name) values ('fi', 'suomi');
insert into language(code, name) values ('fj', 'vosa Vakaviti');
insert into language(code, name) values ('fo', 'føroyskt');
insert into language(code, name) values ('fr', 'Français');
insert into language(code, name) values ('fy', 'Frysk');
insert into language(code, name) values ('ga', 'Gaeilge');
insert into language(code, name) values ('gd', 'Gàidhlig');
insert into language(code, name) values ('gl', 'galego');
insert into language(code, name) values ('gn', E'Avañe\'');
insert into language(code, name) values ('gu', 'ગુજરાતી');
insert into language(code, name) values ('gv', 'Gaelg');
insert into language(code, name) values ('ha', 'هَوُسَ');
insert into language(code, name) values ('he', 'עברית');
insert into language(code, name) values ('hi', 'हिन्दी');
insert into language(code, name) values ('ho', 'Hiri Motu');
insert into language(code, name) values ('hr', 'Hrvatski');
insert into language(code, name) values ('ht', 'Kreyòl ayisyen');
insert into language(code, name) values ('hu', 'magyar');
insert into language(code, name) values ('hy', 'Հայերեն');
insert into language(code, name) values ('hz', 'Otjiherero');
insert into language(code, name) values ('ia', 'Interlingua');
insert into language(code, name) values ('id', 'Bahasa Indonesia');
insert into language(code, name) values ('ie', 'Interlingue');
insert into language(code, name) values ('ig', 'Asụsụ Igbo');
insert into language(code, name) values ('ii', 'ꆈꌠ꒿ Nuosuhxop');
insert into language(code, name) values ('ik', 'Iñupiaq');
insert into language(code, name) values ('io', 'Ido');
insert into language(code, name) values ('is', 'Íslenska');
insert into language(code, name) values ('it', 'Italiano');
insert into language(code, name) values ('iu', 'ᐃᓄᒃᑎᑐᑦ');
insert into language(code, name) values ('ja', '日本語');
insert into language(code, name) values ('jv', 'basa Jawa');
insert into language(code, name) values ('ka', 'ქართული');
insert into language(code, name) values ('kg', 'Kikongo');
insert into language(code, name) values ('ki', 'Gĩkũyũ');
insert into language(code, name) values ('kj', 'Kuanyama');
insert into language(code, name) values ('kk', 'қазақ тілі');
insert into language(code, name) values ('kl', 'kalaallisut');
insert into language(code, name) values ('km', 'ខេមរភាសា');
insert into language(code, name) values ('kn', 'ಕನ್ನಡ');
insert into language(code, name) values ('ko', '한국어');
insert into language(code, name) values ('kr', 'Kanuri');
insert into language(code, name) values ('ks', 'कश्मीरी');
insert into language(code, name) values ('ku', 'Kurdî');
insert into language(code, name) values ('kv', 'коми кыв');
insert into language(code, name) values ('kw', 'Kernewek');
insert into language(code, name) values ('ky', 'Кыргызча');
insert into language(code, name) values ('la', 'latine');
insert into language(code, name) values ('lb', 'Lëtzebuergesch');
insert into language(code, name) values ('lg', 'Luganda');
insert into language(code, name) values ('li', 'Limburgs');
insert into language(code, name) values ('ln', 'Lingála');
insert into language(code, name) values ('lo', 'ພາສາລາວ');
insert into language(code, name) values ('lt', 'lietuvių kalba');
insert into language(code, name) values ('lu', 'Kiluba');
insert into language(code, name) values ('lv', 'latviešu valoda');
insert into language(code, name) values ('mg', 'fiteny malagasy');
insert into language(code, name) values ('mh', 'Kajin M̧ajeļ');
insert into language(code, name) values ('mi', 'te reo Māori');
insert into language(code, name) values ('mk', 'македонски јазик');
insert into language(code, name) values ('ml', 'മലയാളം');
insert into language(code, name) values ('mn', 'Монгол хэл');
insert into language(code, name) values ('mr', 'मराठी');
insert into language(code, name) values ('ms', 'Bahasa Melayu');
insert into language(code, name) values ('mt', 'Malti');
insert into language(code, name) values ('my', 'ဗမာစာ');
insert into language(code, name) values ('na', 'Dorerin Naoero');
insert into language(code, name) values ('nb', 'Norsk bokmål');
insert into language(code, name) values ('nd', 'isiNdebele');
insert into language(code, name) values ('ne', 'नेपाली');
insert into language(code, name) values ('ng', 'Owambo');
insert into language(code, name) values ('nl', 'Nederlands');
insert into language(code, name) values ('nn', 'Norsk nynorsk');
insert into language(code, name) values ('no', 'Norsk');
insert into language(code, name) values ('nr', 'isiNdebele');
insert into language(code, name) values ('nv', 'Diné bizaad');
insert into language(code, name) values ('ny', 'chiCheŵa');
insert into language(code, name) values ('oc', 'occitan');
insert into language(code, name) values ('oj', 'ᐊᓂᔑᓈᐯᒧᐎᓐ');
insert into language(code, name) values ('om', 'Afaan Oromoo');
insert into language(code, name) values ('or', 'ଓଡ଼ିଆ');
insert into language(code, name) values ('os', 'ирон æвзаг');
insert into language(code, name) values ('pa', 'ਪੰਜਾਬੀ');
insert into language(code, name) values ('pi', 'पाऴि');
insert into language(code, name) values ('pl', 'Polski');
insert into language(code, name) values ('ps', 'پښتو');
insert into language(code, name) values ('pt', 'Português');
insert into language(code, name) values ('qu', 'Runa Simi');
insert into language(code, name) values ('rm', 'rumantsch grischun');
insert into language(code, name) values ('rn', 'Ikirundi');
insert into language(code, name) values ('ro', 'Română');
insert into language(code, name) values ('ru', 'Русский');
insert into language(code, name) values ('rw', 'Ikinyarwanda');
insert into language(code, name) values ('sa', 'संस्कृतम्');
insert into language(code, name) values ('sc', 'sardu');
insert into language(code, name) values ('sd', 'सिन्धी');
insert into language(code, name) values ('se', 'Davvisámegiella');
insert into language(code, name) values ('sg', 'yângâ tî sängö');
insert into language(code, name) values ('si', 'සිංහල');
insert into language(code, name) values ('sk', 'slovenčina');
insert into language(code, name) values ('sl', 'slovenščina');
insert into language(code, name) values ('sm', E'gagana fa\'a Samoa');
insert into language(code, name) values ('sn', 'chiShona');
insert into language(code, name) values ('so', 'Soomaaliga');
insert into language(code, name) values ('sq', 'Shqip');
insert into language(code, name) values ('sr', 'српски језик');
insert into language(code, name) values ('ss', 'SiSwati');
insert into language(code, name) values ('st', 'Sesotho');
insert into language(code, name) values ('su', 'Basa Sunda');
insert into language(code, name) values ('sv', 'Svenska');
insert into language(code, name) values ('sw', 'Kiswahili');
insert into language(code, name) values ('ta', 'தமிழ்');
insert into language(code, name) values ('te', 'తెలుగు');
insert into language(code, name) values ('tg', 'тоҷикӣ');
insert into language(code, name) values ('th', 'ไทย');
insert into language(code, name) values ('ti', 'ትግርኛ');
insert into language(code, name) values ('tk', 'Türkmençe');
insert into language(code, name) values ('tl', 'Wikang Tagalog');
insert into language(code, name) values ('tn', 'Setswana');
insert into language(code, name) values ('to', 'faka Tonga');
insert into language(code, name) values ('tr', 'Türkçe');
insert into language(code, name) values ('ts', 'Xitsonga');
insert into language(code, name) values ('tt', 'татар теле');
insert into language(code, name) values ('tw', 'Twi');
insert into language(code, name) values ('ty', 'Reo Tahiti');
insert into language(code, name) values ('ug', 'ئۇيغۇرچە‎');
insert into language(code, name) values ('uk', 'Українська');
insert into language(code, name) values ('ur', 'اردو');
insert into language(code, name) values ('uz', 'Ўзбек');
insert into language(code, name) values ('ve', 'Tshivenḓa');
insert into language(code, name) values ('vi', 'Tiếng Việt');
insert into language(code, name) values ('vo', 'Volapük');
insert into language(code, name) values ('wa', 'walon');
insert into language(code, name) values ('wo', 'Wollof');
insert into language(code, name) values ('xh', 'isiXhosa');
insert into language(code, name) values ('yi', 'ייִדיש');
insert into language(code, name) values ('yo', 'Yorùbá');
insert into language(code, name) values ('za', 'Saɯ cueŋƅ');
insert into language(code, name) values ('zh', '中文');
insert into language(code, name) values ('zu', 'isiZulu');