diff --git a/Cargo.lock b/Cargo.lock index d3520d7e8..b610153a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/crates/db_schema/Cargo.toml b/crates/db_schema/Cargo.toml index 1ede01c9b..e5f749387 100644 --- a/crates/db_schema/Cargo.toml +++ b/crates/db_schema/Cargo.toml @@ -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 } diff --git a/crates/db_schema/src/impls/language.rs b/crates/db_schema/src/impls/language.rs new file mode 100644 index 000000000..fef2fcf11 --- /dev/null +++ b/crates/db_schema/src/impls/language.rs @@ -0,0 +1,31 @@ +use crate::source::language::Language; +use diesel::{result::Error, PgConnection, RunQueryDsl}; + +impl Language { + pub fn read_all(conn: &PgConnection) -> Result, Error> { + use crate::schema::language::dsl::*; + language.load::(conn) + } + + pub fn read_from_code(code_: &str, conn: &PgConnection) -> Result { + use crate::schema::language::dsl::*; + language.find(code.eq(code_)).load::(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); + } +} diff --git a/crates/db_schema/src/impls/mod.rs b/crates/db_schema/src/impls/mod.rs index c96e3a623..d7544a609 100644 --- a/crates/db_schema/src/impls/mod.rs +++ b/crates/db_schema/src/impls/mod.rs @@ -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; diff --git a/crates/db_schema/src/newtypes.rs b/crates/db_schema/src/newtypes.rs index 88079b84f..8228c6fe4 100644 --- a/crates/db_schema/src/newtypes.rs +++ b/crates/db_schema/src/newtypes.rs @@ -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 { - let mut all: Vec = 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()) - } -} diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index 30a6e6622..57023a3c4 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -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 ); diff --git a/crates/db_schema/src/source/language.rs b/crates/db_schema/src/source/language.rs new file mode 100644 index 000000000..97377c9c2 --- /dev/null +++ b/crates/db_schema/src/source/language.rs @@ -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, +} diff --git a/crates/db_schema/src/source/local_user.rs b/crates/db_schema/src/source/local_user.rs index 5cfa36da2..c59c3ef74 100644 --- a/crates/db_schema/src/source/local_user.rs +++ b/crates/db_schema/src/source/local_user.rs @@ -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, + pub discussion_languages: Vec, } // TODO redo these, check table defaults @@ -50,7 +50,7 @@ pub struct LocalUserForm { pub show_new_post_notifs: Option, pub email_verified: Option, pub accepted_application: Option, - pub discussion_languages: Option>, + pub discussion_languages: Option>, } /// 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, + pub discussion_languages: Vec, } diff --git a/crates/db_schema/src/source/mod.rs b/crates/db_schema/src/source/mod.rs index f2ff5f78e..cdef07ea9 100644 --- a/crates/db_schema/src/source/mod.rs +++ b/crates/db_schema/src/source/mod.rs @@ -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; diff --git a/crates/db_schema/src/source/post.rs b/crates/db_schema/src/source/post.rs index e76c92755..5914685f0 100644 --- a/crates/db_schema/src/source/post.rs +++ b/crates/db_schema/src/source/post.rs @@ -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, 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, pub ap_id: Option, pub local: Option, - pub language: Option, + pub language: Option, } #[derive(PartialEq, Debug)] diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index f4012d649..d7940df68 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -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, @@ -835,23 +835,17 @@ mod tests { let data = init_data(&conn); let mut read_post_listing_french = PostQueryBuilder::create(&conn) - .listing_type(ListingType::Community) - .sort(SortType::New) - .community_id(data.inserted_community.id); + .listing_type(ListingType::Community) + .sort(SortType::New) + .community_id(data.inserted_community.id); let fr = LanguageIdentifier::new("fr"); read_post_listing_french.languages = Some(vec![fr]); let read_post_listing_french = read_post_listing_french.list().unwrap(); 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); } diff --git a/migrations/2022-05-11-123144_language-tags/up.sql b/migrations/2022-05-11-123144_language-tags/up.sql deleted file mode 100644 index 4d1dd76d9..000000000 --- a/migrations/2022-05-11-123144_language-tags/up.sql +++ /dev/null @@ -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'; diff --git a/migrations/2022-05-11-123144_language-tags/down.sql b/migrations/2022-06-21-123144_language-tags/down.sql similarity index 85% rename from migrations/2022-05-11-123144_language-tags/down.sql rename to migrations/2022-06-21-123144_language-tags/down.sql index 308fc38b1..974f85352 100644 --- a/migrations/2022-05-11-123144_language-tags/down.sql +++ b/migrations/2022-06-21-123144_language-tags/down.sql @@ -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; diff --git a/migrations/2022-06-21-123144_language-tags/up.sql b/migrations/2022-06-21-123144_language-tags/up.sql new file mode 100644 index 000000000..58031024d --- /dev/null +++ b/migrations/2022-06-21-123144_language-tags/up.sql @@ -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');