diff --git a/migrations/postgres/2018-12-08-175515_constraints/down.sql b/migrations/postgres/2018-12-08-175515_constraints/down.sql new file mode 100644 index 00000000..e189dc22 --- /dev/null +++ b/migrations/postgres/2018-12-08-175515_constraints/down.sql @@ -0,0 +1,24 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE api_tokens DROP CONSTRAINT IF EXISTS api_tokens_unique_value; +ALTER TABLE blog_authors DROP CONSTRAINT IF EXISTS blog_author_unique; +ALTER TABLE blogs DROP CONSTRAINT IF EXISTS blog_unique; +ALTER TABLE blogs DROP CONSTRAINT IF EXISTS blog_unique_ap_url; +ALTER TABLE blogs DROP CONSTRAINT IF EXISTS blog_unique_outbox; +ALTER TABLE blogs DROP CONSTRAINT IF EXISTS blog_unique_inbox; +ALTER TABLE comments DROP CONSTRAINT IF EXISTS comments_unique_ap_url; +ALTER TABLE follows DROP CONSTRAINT IF EXISTS follows_unique_ap_url; +ALTER TABLE instances DROP CONSTRAINT IF EXISTS instance_unique_domain; +ALTER TABLE likes DROP CONSTRAINT IF EXISTS likes_unique; +ALTER TABLE likes DROP CONSTRAINT IF EXISTS likes_unique_ap_url; +ALTER TABLE mentions DROP CONSTRAINT IF EXISTS mentions_unique_ap_url; +ALTER TABLE post_authors DROP CONSTRAINT IF EXISTS post_authors_unique; +ALTER TABLE posts DROP CONSTRAINT IF EXISTS post_unique_slug; +ALTER TABLE posts DROP CONSTRAINT IF EXISTS post_unique_ap_url; +ALTER TABLE reshares DROP CONSTRAINT IF EXISTS reshares_unique; +ALTER TABLE reshares DROP CONSTRAINT IF EXISTS reshares_unique_ap_url; +ALTER TABLE tags DROP CONSTRAINT IF EXISTS tags_unique; +ALTER TABLE users DROP CONSTRAINT IF EXISTS users_unique; +ALTER TABLE users DROP CONSTRAINT IF EXISTS users_unique_inbox; +ALTER TABLE users DROP CONSTRAINT IF EXISTS users_unique_outbox; +ALTER TABLE users DROP CONSTRAINT IF EXISTS users_unique_ap_url; +ALTER TABLE users DROP CONSTRAINT IF EXISTS users_unique_followers_url; diff --git a/migrations/postgres/2018-12-08-175515_constraints/up.sql b/migrations/postgres/2018-12-08-175515_constraints/up.sql new file mode 100644 index 00000000..21b6f3b6 --- /dev/null +++ b/migrations/postgres/2018-12-08-175515_constraints/up.sql @@ -0,0 +1,83 @@ +-- Your SQL goes here + +-- First, we delete the already duplicated data so that the constraint can be correctly applied + +DELETE FROM api_tokens a USING api_tokens b WHERE + a.id > b.id + AND a.value = b.value; +DELETE FROM blog_authors a USING blog_authors b WHERE + a.id > b.id + AND a.blog_id = b.blog_id + AND a.author_id = b.author_id; +DELETE FROM blogs a USING blogs b WHERE + a.id > b.id + AND ((a.actor_id = b.actor_id AND a.instance_id = b.instance_id) + OR a.ap_url = b.ap_url + OR a.outbox_url = b.outbox_url + OR a.inbox_url = b.inbox_url); +DELETE FROM comments a USING comments b WHERE + a.id > b.id + AND (a.ap_url = b.ap_url); +DELETE FROM follows a USING follows b + WHERE a.id > b.id + AND (a.ap_url = b.ap_url); +DELETE FROM instances a USING instances b WHERE + a.id > b.id + AND (a.public_domain = b.public_domain); +DELETE FROM likes a USING likes b WHERE + a.id > b.id + AND (a.ap_url = b.ap_url + OR (a.user_id = b.user_id AND a.post_id = b.post_id)); +DELETE FROM mentions a USING mentions b WHERE + a.id > b.id + AND (a.ap_url = b.ap_url); +DELETE FROM post_authors a USING post_authors b WHERE + a.id > b.id + AND a.author_id = b.author_id + AND a.post_id = b.post_id; +DELETE FROM posts a USING posts b WHERE + a.id > b.id + AND ((a.ap_url = b.ap_url) + OR (a.blog_id = b.blog_id AND a.slug = b.slug)); +DELETE FROM reshares a USING reshares b WHERE + a.id > b.id + AND (a.ap_url = b.ap_url + OR (a.user_id = b.user_id AND a.post_id = b.post_id)); +DELETE FROM tags a USING tags b WHERE + a.id > b.id + AND a.tag = b.tag + AND a.post_id = b.post_id + AND a.is_hashtag = b.is_hashtag; +DELETE FROM users a USING users b WHERE + a.id > b.id + AND (a.ap_url = b.ap_url + OR (a.username = b.username AND a.instance_id = b.instance_id) + OR a.outbox_url = b.outbox_url + OR a.inbox_url = b.inbox_url + OR a.followers_endpoint = b.followers_endpoint); + +-- Then we add the UNIQUE constraints + +ALTER TABLE api_tokens ADD CONSTRAINT api_tokens_unique_value UNIQUE (value); +ALTER TABLE blog_authors ADD CONSTRAINT blog_author_unique UNIQUE (blog_id, author_id); +ALTER TABLE blogs ADD CONSTRAINT blog_unique UNIQUE (actor_id, instance_id); +ALTER TABLE blogs ADD CONSTRAINT blog_unique_ap_url UNIQUE (ap_url); +ALTER TABLE blogs ADD CONSTRAINT blog_unique_outbox UNIQUE (outbox_url); +ALTER TABLE blogs ADD CONSTRAINT blog_unique_inbox UNIQUE (inbox_url); +ALTER TABLE comments ADD CONSTRAINT comments_unique_ap_url UNIQUE (ap_url); +ALTER TABLE follows ADD CONSTRAINT follows_unique_ap_url UNIQUE (ap_url); +ALTER TABLE instances ADD CONSTRAINT instance_unique_domain UNIQUE (public_domain); +ALTER TABLE likes ADD CONSTRAINT likes_unique UNIQUE (user_id, post_id); +ALTER TABLE likes ADD CONSTRAINT likes_unique_ap_url UNIQUE (ap_url); +ALTER TABLE mentions ADD CONSTRAINT mentions_unique_ap_url UNIQUE (ap_url); +ALTER TABLE post_authors ADD CONSTRAINT post_authors_unique UNIQUE (post_id, author_id); +ALTER TABLE posts ADD CONSTRAINT post_unique_slug UNIQUE (blog_id, slug); +ALTER TABLE posts ADD CONSTRAINT post_unique_ap_url UNIQUE (ap_url); +ALTER TABLE reshares ADD CONSTRAINT reshares_unique UNIQUE (user_id, post_id); +ALTER TABLE reshares ADD CONSTRAINT reshares_unique_ap_url UNIQUE (ap_url); +ALTER TABLE tags ADD CONSTRAINT tags_unique UNIQUE (tag, post_id, is_hashtag); +ALTER TABLE users ADD CONSTRAINT users_unique UNIQUE (username, instance_id); +ALTER TABLE users ADD CONSTRAINT users_unique_inbox UNIQUE (inbox_url); +ALTER TABLE users ADD CONSTRAINT users_unique_outbox UNIQUE (outbox_url); +ALTER TABLE users ADD CONSTRAINT users_unique_ap_url UNIQUE (ap_url); +ALTER TABLE users ADD CONSTRAINT users_unique_followers_url UNIQUE (followers_endpoint); diff --git a/migrations/sqlite/2018-12-08-182930_constraints/down.sql b/migrations/sqlite/2018-12-08-182930_constraints/down.sql new file mode 100644 index 00000000..5b196d58 --- /dev/null +++ b/migrations/sqlite/2018-12-08-182930_constraints/down.sql @@ -0,0 +1,178 @@ +-- This file should undo anything in `up.sql` +CREATE TABLE api_tokens2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + value TEXT NOT NULL, + scopes TEXT NOT NULL, + app_id INTEGER NOT NULL REFERENCES apps(id) ON DELETE CASCADE, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE +); + +INSERT INTO api_tokens2 SELECT * FROM api_tokens; +DROP TABLE api_tokens; +ALTER TABLE api_tokens2 RENAME TO api_tokens; + +CREATE TABLE blog_authors2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + blog_id INTEGER REFERENCES blogs(id) ON DELETE CASCADE NOT NULL, + author_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + is_owner BOOLEAN NOT NULL DEFAULT 'f' +); + +INSERT INTO blog_authors2 SELECT * FROM blog_authors; +DROP TABLE blog_authors; +ALTER TABLE blog_authors2 RENAME TO blog_authors; + +CREATE TABLE blogs2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + actor_id VARCHAR NOT NULL, + title VARCHAR NOT NULL, + summary TEXT NOT NULL DEFAULT '', + outbox_url VARCHAR NOT NULL, + inbox_url VARCHAR NOT NULL, + instance_id INTEGER REFERENCES instances(id) ON DELETE CASCADE NOT NULL, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url text not null default '', + private_key TEXT, + public_key TEXT NOT NULL DEFAULT '' +) + +INSERT INTO blogs2 SELECT * FROM blogs; +DROP TABLE blogs; +ALTER TABLE blogs2 RENAME TO blogs; + +CREATE TABLE comments2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + content TEXT NOT NULL DEFAULT '', + in_response_to_id INTEGER REFERENCES comments(id), + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE NOT NULL, + author_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url VARCHAR, + sensitive BOOLEAN NOT NULL DEFAULT 'f', + spoiler_text TEXT NOT NULL DEFAULT '' +); + +INSERT INTO comments2 SELECT * FROM comments; +DROP TABLE comments; +ALTER TABLE comments2 RENAME TO comments; + +CREATE TABLE follows2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + follower_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + following_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + ap_url TEXT NOT NULL default '' +); + +INSERT INTO follows2 SELECT * FROM follows; +DROP TABLE follows; +ALTER TABLE follows2 RENAME TO follows; + +CREATE TABLE instances2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + public_domain VARCHAR NOT NULL, + name VARCHAR NOT NULL, + local BOOLEAN NOT NULL DEFAULT 'f', + blocked BOOLEAN NOT NULL DEFAULT 'f', + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + open_registrations BOOLEAN NOT NULL DEFAULT 't', + short_description TEXT NOT NULL DEFAULT '', + long_description TEXT NOT NULL DEFAULT '', + default_license TEXT NOT NULL DEFAULT 'CC-BY-SA', + long_description_html VARCHAR NOT NULL DEFAULT '', + short_description_html VARCHAR NOT NULL DEFAULT '' +); + +INSERT INTO instances2 SELECT * FROM instances; +DROP TABLE instances; +ALTER TABLE instances2 RENAME TO instances; + +CREATE TABLE likes2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + user_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE NOT NULL, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url VARCHAR NOT NULL default '' +); + +INSERT INTO likes2 SELECT * FROM likes; +DROP TABLE likes; +ALTER TABLE likes2 RENAME TO likes; + +CREATE TABLE mentions2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + mentioned_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE, + comment_id INTEGER REFERENCES comments(id) ON DELETE CASCADE, + ap_url VARCHAR NOT NULL DEFAULT '' +); + +INSERT INTO mentions2 SELECT * FROM mentions; +DROP TABLE mentions; +ALTER TABLE mentions2 RENAME TO mentions; + +CREATE TABLE post_authors2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE NOT NULL, + author_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL +) + +INSERT INTO post_authors2 SELECT * FROM post_authors; +DROP TABLE post_authors; +ALTER TABLE post_authors2 RENAME TO post_authors; + +CREATE TABLE posts2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + blog_id INTEGER REFERENCES blogs(id) ON DELETE CASCADE NOT NULL, + slug VARCHAR NOT NULL, + title VARCHAR NOT NULL, + content TEXT NOT NULL DEFAULT '', + published BOOLEAN NOT NULL DEFAULT 'f', + license VARCHAR NOT NULL DEFAULT 'CC-BY-SA', + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url VARCHAR NOT NULL DEFAULT '', + subtitle TEXT NOT NULL DEFAULT '', + source TEXT NOT NULL DEFAULT '' +); + +INSERT INTO posts2 SELECT * FROM posts; +DROP TABLE posts; +ALTER TABLE posts2 RENAME TO posts; + +CREATE TABLE tags2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + tag TEXT NOT NULL DEFAULT '', + is_hashtag BOOLEAN NOT NULL DEFAULT 'f', + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE NOT NULL +); + +INSERT INTO tags2 SELECT * FROM tags; +DROP TABLE tags; +ALTER TABLE tags2 RENAME TO tags; + +CREATE TABLE users ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + username VARCHAR NOT NULL, + display_name VARCHAR NOT NULL DEFAULT '', + outbox_url VARCHAR NOT NULL, + inbox_url VARCHAR NOT NULL, + is_admin BOOLEAN NOT NULL DEFAULT 'f', + summary TEXT NOT NULL DEFAULT '', + email TEXT, + hashed_password TEXT, + instance_id INTEGER REFERENCES instances(id) ON DELETE CASCADE NOT NULL, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url TEXT NOT NULL default '', + private_key TEXT, + public_key TEXT NOT NULL DEFAULT '', + shared_inbox_url VARCHAR, + followers_endpoint VARCHAR NOT NULL DEFAULT '', + avatar_id INTEGER REFERENCES medias(id) ON DELETE CASCADE, + last_fetched_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (avatar_id) REFERENCES medias(id) ON DELETE SET NULL +); + +INSERT INTO users2 SELECT * FROM users; +DROP TABLE users; +ALTER TABLE users2 RENAME TO users; + diff --git a/migrations/sqlite/2018-12-08-182930_constraints/up.sql b/migrations/sqlite/2018-12-08-182930_constraints/up.sql new file mode 100644 index 00000000..3b94d401 --- /dev/null +++ b/migrations/sqlite/2018-12-08-182930_constraints/up.sql @@ -0,0 +1,186 @@ +-- Your SQL goes here +CREATE TABLE api_tokens2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + value TEXT NOT NULL UNIQUE, + scopes TEXT NOT NULL, + app_id INTEGER NOT NULL REFERENCES apps(id) ON DELETE CASCADE, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE +); + +INSERT INTO api_tokens2 SELECT * FROM api_tokens; +DROP TABLE api_tokens; +ALTER TABLE api_tokens2 RENAME TO api_tokens; + +CREATE TABLE blog_authors2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + blog_id INTEGER REFERENCES blogs(id) ON DELETE CASCADE NOT NULL, + author_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + is_owner BOOLEAN NOT NULL DEFAULT 'f', + CONSTRAINT blog_authors_unique UNIQUE (blog_id, author_id) +); + +INSERT INTO blog_authors2 SELECT * FROM blog_authors; +DROP TABLE blog_authors; +ALTER TABLE blog_authors2 RENAME TO blog_authors; + +CREATE TABLE blogs2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + actor_id VARCHAR NOT NULL, + title VARCHAR NOT NULL, + summary TEXT NOT NULL DEFAULT '', + outbox_url VARCHAR NOT NULL UNIQUE, + inbox_url VARCHAR NOT NULL UNIQUE, + instance_id INTEGER REFERENCES instances(id) ON DELETE CASCADE NOT NULL, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url text not null default '' UNIQUE, + private_key TEXT, + public_key TEXT NOT NULL DEFAULT '', + CONSTRAINT blog_unique UNIQUE (actor_id, instance_id) +); + +INSERT INTO blogs2 SELECT * FROM blogs; +DROP TABLE blogs; +ALTER TABLE blogs2 RENAME TO blogs; + +CREATE TABLE comments2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + content TEXT NOT NULL DEFAULT '', + in_response_to_id INTEGER REFERENCES comments(id), + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE NOT NULL, + author_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url VARCHAR UNIQUE, + sensitive BOOLEAN NOT NULL DEFAULT 'f', + spoiler_text TEXT NOT NULL DEFAULT '' +); + +INSERT INTO comments2 SELECT * FROM comments; +DROP TABLE comments; +ALTER TABLE comments2 RENAME TO comments; + +CREATE TABLE follows2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + follower_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + following_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + ap_url TEXT NOT NULL default '' UNIQUE +); + +INSERT INTO follows2 SELECT * FROM follows; +DROP TABLE follows; +ALTER TABLE follows2 RENAME TO follows; + +CREATE TABLE instances2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + public_domain VARCHAR NOT NULL UNIQUE, + name VARCHAR NOT NULL, + local BOOLEAN NOT NULL DEFAULT 'f', + blocked BOOLEAN NOT NULL DEFAULT 'f', + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + open_registrations BOOLEAN NOT NULL DEFAULT 't', + short_description TEXT NOT NULL DEFAULT '', + long_description TEXT NOT NULL DEFAULT '', + default_license TEXT NOT NULL DEFAULT 'CC-BY-SA', + long_description_html VARCHAR NOT NULL DEFAULT '', + short_description_html VARCHAR NOT NULL DEFAULT '' +); + +INSERT INTO instances2 SELECT * FROM instances; +DROP TABLE instances; +ALTER TABLE instances2 RENAME TO instances; + +CREATE TABLE likes2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + user_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE NOT NULL, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url VARCHAR NOT NULL default '' UNIQUE, + CONSTRAINT likes_unique UNIQUE (user_id, post_id) +); + +INSERT INTO likes2 SELECT * FROM likes; +DROP TABLE likes; +ALTER TABLE likes2 RENAME TO likes; + +CREATE TABLE mentions2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + mentioned_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE, + comment_id INTEGER REFERENCES comments(id) ON DELETE CASCADE, + ap_url VARCHAR NOT NULL DEFAULT '' UNIQUE +); + +INSERT INTO mentions2 SELECT * FROM mentions; +DROP TABLE mentions; +ALTER TABLE mentions2 RENAME TO mentions; + +CREATE TABLE post_authors2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE NOT NULL, + author_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, + CONSTRAINT blog_authors_unique UNIQUE (post_id, author_id) +); + +INSERT INTO post_authors2 SELECT * FROM post_authors; +DROP TABLE post_authors; +ALTER TABLE post_authors2 RENAME TO post_authors; + +CREATE TABLE posts2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + blog_id INTEGER REFERENCES blogs(id) ON DELETE CASCADE NOT NULL, + slug VARCHAR NOT NULL, + title VARCHAR NOT NULL, + content TEXT NOT NULL DEFAULT '', + published BOOLEAN NOT NULL DEFAULT 'f', + license VARCHAR NOT NULL DEFAULT 'CC-BY-SA', + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url VARCHAR NOT NULL DEFAULT '' UNIQUE, + subtitle TEXT NOT NULL DEFAULT '', + source TEXT NOT NULL DEFAULT '', + cover_id INTEGER REFERENCES medias(id) DEFAULT NULL, + CONSTRAINT blog_authors_unique UNIQUE (blog_id, slug) +); + +INSERT INTO posts2 SELECT * FROM posts; +DROP TABLE posts; +ALTER TABLE posts2 RENAME TO posts; + +CREATE TABLE tags2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + tag TEXT NOT NULL DEFAULT '', + is_hashtag BOOLEAN NOT NULL DEFAULT 'f', + post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE NOT NULL, + CONSTRAINT blog_authors_unique UNIQUE (tag, is_hashtag, post_id) +); + +INSERT INTO tags2 SELECT * FROM tags; +DROP TABLE tags; +ALTER TABLE tags2 RENAME TO tags; + +CREATE TABLE users2 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + username VARCHAR NOT NULL, + display_name VARCHAR NOT NULL DEFAULT '', + outbox_url VARCHAR NOT NULL UNIQUE, + inbox_url VARCHAR NOT NULL UNIQUE, + is_admin BOOLEAN NOT NULL DEFAULT 'f', + summary TEXT NOT NULL DEFAULT '', + email TEXT, + hashed_password TEXT, + instance_id INTEGER REFERENCES instances(id) ON DELETE CASCADE NOT NULL, + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url TEXT NOT NULL default '' UNIQUE, + private_key TEXT, + public_key TEXT NOT NULL DEFAULT '', + shared_inbox_url VARCHAR, + followers_endpoint VARCHAR NOT NULL DEFAULT '' UNIQUE, + avatar_id INTEGER REFERENCES medias(id) ON DELETE CASCADE, + last_fetched_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (avatar_id) REFERENCES medias(id) ON DELETE SET NULL, + CONSTRAINT blog_authors_unique UNIQUE (username, instance_id) +); + +INSERT INTO users2 SELECT * FROM users; +DROP TABLE users; +ALTER TABLE users2 RENAME TO users; + diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 318eb529..55292351 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -513,36 +513,35 @@ pub(crate) mod tests { use search::tests::get_searcher; use Connection as Conn; - pub(crate) fn fill_database(conn: &Conn) -> Vec { + pub(crate) fn fill_database(conn: &Conn) -> (Vec, Vec) { instance_tests::fill_database(conn); let users = usersTests::fill_database(conn); - let blogs = vec![ - NewBlog::new_local( - "BlogName".to_owned(), - "Blog name".to_owned(), - "This is a small blog".to_owned(), - Instance::local_id(conn), - ), - NewBlog::new_local( + let blog1 = Blog::insert(conn, NewBlog::new_local( + "BlogName".to_owned(), + "Blog name".to_owned(), + "This is a small blog".to_owned(), + Instance::local_id(conn), + )); + blog1.update_boxes(conn); + let blog2 = Blog::insert(conn, NewBlog::new_local( "MyBlog".to_owned(), "My blog".to_owned(), "Welcome to my blog".to_owned(), Instance::local_id(conn), - ), - NewBlog::new_local( + )); + blog2.update_boxes(conn); + let blog3 = Blog::insert(conn, NewBlog::new_local( "WhyILikePlume".to_owned(), "Why I like Plume".to_owned(), "In this blog I will explay you why I like Plume so much".to_owned(), Instance::local_id(conn), - ), - ].into_iter() - .map(|nb| Blog::insert(conn, nb)) - .collect::>(); + )); + blog3.update_boxes(conn); BlogAuthor::insert( conn, NewBlogAuthor { - blog_id: blogs[0].id, + blog_id: blog1.id, author_id: users[0].id, is_owner: true, }, @@ -551,7 +550,7 @@ pub(crate) mod tests { BlogAuthor::insert( conn, NewBlogAuthor { - blog_id: blogs[0].id, + blog_id: blog1.id, author_id: users[1].id, is_owner: false, }, @@ -560,7 +559,7 @@ pub(crate) mod tests { BlogAuthor::insert( conn, NewBlogAuthor { - blog_id: blogs[1].id, + blog_id: blog2.id, author_id: users[1].id, is_owner: true, }, @@ -569,12 +568,12 @@ pub(crate) mod tests { BlogAuthor::insert( conn, NewBlogAuthor { - blog_id: blogs[2].id, + blog_id: blog3.id, author_id: users[2].id, is_owner: true, }, ); - blogs + (users, vec![ blog1, blog2, blog3 ]) } #[test] @@ -604,29 +603,29 @@ pub(crate) mod tests { fn authors() { let conn = &db(); conn.test_transaction::<_, (), _>(|| { - let user = usersTests::fill_database(conn); - fill_database(conn); + let (user, _) = fill_database(conn); - let blog = vec![ - Blog::insert( - conn, - NewBlog::new_local( - "SomeName".to_owned(), - "Some name".to_owned(), - "This is some blog".to_owned(), - Instance::local_id(conn), - ), + let b1 = Blog::insert( + conn, + NewBlog::new_local( + "SomeName".to_owned(), + "Some name".to_owned(), + "This is some blog".to_owned(), + Instance::local_id(conn), ), - Blog::insert( - conn, - NewBlog::new_local( - "Blog".to_owned(), - "Blog".to_owned(), - "I've named my blog Blog".to_owned(), - Instance::local_id(conn), - ), + ); + b1.update_boxes(conn); + let b2 = Blog::insert( + conn, + NewBlog::new_local( + "Blog".to_owned(), + "Blog".to_owned(), + "I've named my blog Blog".to_owned(), + Instance::local_id(conn), ), - ]; + ); + b2.update_boxes(conn); + let blog = vec![ b1, b2 ]; BlogAuthor::insert( conn, @@ -756,7 +755,7 @@ pub(crate) mod tests { fn delete() { let conn = &db(); conn.test_transaction::<_, (), _>(|| { - let blogs = fill_database(conn); + let (_, blogs) = fill_database(conn); blogs[0].delete(conn, &get_searcher()); assert!(Blog::get(conn, blogs[0].id).is_none()); @@ -770,29 +769,29 @@ pub(crate) mod tests { let conn = &db(); conn.test_transaction::<_, (), _>(|| { let searcher = get_searcher(); - let user = usersTests::fill_database(conn); - fill_database(conn); + let (user, _) = fill_database(conn); - let blog = vec![ - Blog::insert( - conn, - NewBlog::new_local( - "SomeName".to_owned(), - "Some name".to_owned(), - "This is some blog".to_owned(), - Instance::local_id(conn), - ), + let b1 = Blog::insert( + conn, + NewBlog::new_local( + "SomeName".to_owned(), + "Some name".to_owned(), + "This is some blog".to_owned(), + Instance::local_id(conn), ), - Blog::insert( - conn, - NewBlog::new_local( - "Blog".to_owned(), - "Blog".to_owned(), - "I've named my blog Blog".to_owned(), - Instance::local_id(conn), - ), + ); + b1.update_boxes(conn); + let b2 = Blog::insert( + conn, + NewBlog::new_local( + "Blog".to_owned(), + "Blog".to_owned(), + "I've named my blog Blog".to_owned(), + Instance::local_id(conn), ), - ]; + ); + b2.update_boxes(conn); + let blog = vec![ b1, b2 ]; BlogAuthor::insert( conn, diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index bb3c4e81..ccf6516c 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -220,7 +220,7 @@ pub(crate) mod tests { use users::tests as usersTests; use Connection as Conn; - pub(crate) fn fill_database(conn: &Conn) -> Vec { + pub(crate) fn fill_database(conn: &Conn) -> (Vec, Vec) { let mut wd = current_dir().unwrap().to_path_buf(); while wd.pop() { if wd.join(".git").exists() { @@ -236,7 +236,7 @@ pub(crate) mod tests { let f2 = "static/media/2.mp3".to_owned(); fs::write(f1.clone(), []).unwrap(); fs::write(f2.clone(), []).unwrap(); - vec![ + (users, vec![ NewMedia { file_path: f1, alt_text: "some alt".to_owned(), @@ -266,7 +266,7 @@ pub(crate) mod tests { }, ].into_iter() .map(|nm| Media::insert(conn, nm)) - .collect() + .collect()) } pub(crate) fn clean(conn: &Conn) { @@ -282,8 +282,7 @@ pub(crate) mod tests { fn delete() { let conn = &db(); conn.test_transaction::<_, (), _>(|| { - let user = usersTests::fill_database(conn)[0].id; - fill_database(conn); + let user = fill_database(conn).0[0].id; let path = "static/media/test_deletion".to_owned(); fs::write(path.clone(), []).unwrap(); @@ -316,10 +315,9 @@ pub(crate) mod tests { fn set_owner() { let conn = &db(); conn.test_transaction::<_, (), _>(|| { - let users = usersTests::fill_database(conn); + let (users, _) = fill_database(conn); let u1 = &users[0]; let u2 = &users[1]; - fill_database(conn); let path = "static/media/test_set_owner".to_owned(); fs::write(path.clone(), []).unwrap(); diff --git a/plume-models/src/search/mod.rs b/plume-models/src/search/mod.rs index 35776ae8..30c08fc6 100644 --- a/plume-models/src/search/mod.rs +++ b/plume-models/src/search/mod.rs @@ -117,7 +117,7 @@ pub(crate) mod tests { let conn = &db(); conn.test_transaction::<_, (), _>(|| { let searcher = get_searcher(); - let blog = &fill_database(conn)[0]; + let blog = &fill_database(conn).1[0]; let author = &blog.list_authors(conn)[0]; let title = random_hex()[..8].to_owned(); diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 92b279bf..1187ec79 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -998,39 +998,37 @@ pub(crate) mod tests { pub(crate) fn fill_database(conn: &Conn) -> Vec { instance_tests::fill_database(conn); - let local_user = vec![ - NewUser::new_local( - conn, - "admin".to_owned(), - "The admin".to_owned(), - true, - "Hello there, I'm the admin", - "admin@example.com".to_owned(), - "invalid_admin_password".to_owned(), - ), - NewUser::new_local( - conn, - "user".to_owned(), - "Some user".to_owned(), - false, - "Hello there, I'm no one", - "user@example.com".to_owned(), - "invalid_user_password".to_owned(), - ), - NewUser::new_local( - conn, - "other".to_owned(), - "Another user".to_owned(), - false, - "Hello there, I'm someone else", - "other@example.com".to_owned(), - "invalid_other_password".to_owned(), - ), - ]; - for u in local_user.iter() { - u.update_boxes(conn); - } - local_user + let admin = NewUser::new_local( + conn, + "admin".to_owned(), + "The admin".to_owned(), + true, + "Hello there, I'm the admin", + "admin@example.com".to_owned(), + "invalid_admin_password".to_owned(), + ); + admin.update_boxes(conn); + let user = NewUser::new_local( + conn, + "user".to_owned(), + "Some user".to_owned(), + false, + "Hello there, I'm no one", + "user@example.com".to_owned(), + "invalid_user_password".to_owned(), + ); + user.update_boxes(conn); + let other = NewUser::new_local( + conn, + "other".to_owned(), + "Another user".to_owned(), + false, + "Hello there, I'm someone else", + "other@example.com".to_owned(), + "invalid_other_password".to_owned(), + ); + other.update_boxes(conn); + vec![ admin, user, other ] } #[test]