update follows table, rename importer

This commit is contained in:
Joe Ardent 2024-01-15 15:11:39 -08:00
parent 88b870031e
commit 3caefad767
5 changed files with 41 additions and 37 deletions

View file

@ -12,8 +12,13 @@ create table if not exists users (
last_seen int, last_seen int,
pwhash blob not null, pwhash blob not null,
invited_by blob not null, invited_by blob not null,
last_updated int not null default (unixepoch()) is_active int not null default 1,
last_updated int not null default (unixepoch()),
foreign key (invited_by) references users (id)
); );
create index if not exists users_username_dex on users (lower(username));
create index if not exists users_email_dex on users (lower(email));
create index if not exists users_invited_by_dex on users (invited_by);
-- invitations -- invitations
create table if not exists invites ( create table if not exists invites (
@ -24,6 +29,8 @@ create table if not exists invites (
last_updated int not null default (unixepoch()), last_updated int not null default (unixepoch()),
foreign key (owner) references users (id) on delete cascade on update no action foreign key (owner) references users (id) on delete cascade on update no action
); );
create index if not exists invites_owner_dex on invites (owner);
-- table of things to watch -- table of things to watch
create table if not exists watches ( create table if not exists watches (
@ -37,6 +44,7 @@ create table if not exists watches (
last_updated int not null default (unixepoch()), last_updated int not null default (unixepoch()),
foreign key (added_by) references users (id) foreign key (added_by) references users (id)
); );
create index if not exists watches_title_dex on watches (lower(title));
-- table of what people want to watch -- table of what people want to watch
create table if not exists watch_quests ( create table if not exists watch_quests (
@ -52,15 +60,18 @@ create table if not exists watch_quests (
foreign key (watch) references watches (id) on delete cascade on update no action, foreign key (watch) references watches (id) on delete cascade on update no action,
primary key (user, watch) primary key (user, watch)
); );
create index if not exists quests_user_dex on watch_quests (user);
create index if not exists quests_watch_dex on watch_quests (watch);
-- friend lists; created by trigger at the same time as the user, so no created_at needed
create table if not exists follows ( create table if not exists follows (
user blob not null primary key, follower blob not null,
follows blob, -- possibly empty friends list in some app-specific format followee blob not null,
last_updated int not null default (unixepoch()), created_at int not null default (unixepoch()),
foreign key (user) references users (id) on delete cascade on update no action foreign key (follower) references users (id) on delete cascade on update no action
foreign key (followee) references users (id) on delete cascade on update no action
); );
create index if not exists follows_follower_dex on follows (follower);
create index if not exists follows_followee_dex on follows (followee);
create table if not exists watch_notes ( create table if not exists watch_notes (
id blob not null primary key default (julid_new()), -- a user can have multiple notes about the same thing id blob not null primary key default (julid_new()), -- a user can have multiple notes about the same thing
@ -72,13 +83,7 @@ create table if not exists watch_notes (
foreign key (user) references users (id) on delete cascade on update no action, foreign key (user) references users (id) on delete cascade on update no action,
foreign key (watch) references watches (id) on delete cascade on update no action foreign key (watch) references watches (id) on delete cascade on update no action
); );
-- indices, not needed for follows
create index if not exists users_username_dex on users (lower(username));
create index if not exists users_email_dex on users (lower(email));
create index if not exists watches_title_dex on watches (lower(title));
create index if not exists watches_added_by_dex on watches (added_by);
create index if not exists quests_user_dex on watch_quests (user);
create index if not exists quests_watch_dex on watch_quests (watch);
create index if not exists notes_user_dex on watch_notes (user); create index if not exists notes_user_dex on watch_notes (user);
create index if not exists notes_watch_dex on watch_notes (watch); create index if not exists notes_watch_dex on watch_notes (watch);
-- indices

View file

@ -12,18 +12,6 @@ BEGIN
update invites set last_updated = (select unixepoch()) where id=NEW.id; update invites set last_updated = (select unixepoch()) where id=NEW.id;
END; END;
create trigger if not exists insert_user_follows
after insert on users
BEGIN
insert into follows (user) values (NEW.id);
END;
create trigger if not exists delete_user_follows
after delete on users
BEGIN
delete from follows where user = OLD.id;
END;
create trigger if not exists update_last_updated_watches create trigger if not exists update_last_updated_watches
after update on watches after update on watches
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
@ -38,13 +26,6 @@ BEGIN
update watch_quests set last_updated = (select unixepoch()) where watch=NEW.watch and user=NEW.user; update watch_quests set last_updated = (select unixepoch()) where watch=NEW.watch and user=NEW.user;
END; END;
create trigger if not exists update_last_updated_follows
after update on follows
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
BEGIN
update follows set last_updated = (select unixepoch()) where id=NEW.id;
END;
create trigger if not exists update_last_updated_watch_notes create trigger if not exists update_last_updated_watch_notes
after update on watch_notes after update on watch_notes
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null when OLD.last_updated = NEW.last_updated or OLD.last_updated is null

View file

@ -196,7 +196,6 @@ pub(crate) async fn create_user(
})?; })?;
let invitation = Julid::from_str(invitation).map_err(|_| CreateUserErrorKind::BadInvitation)?; let invitation = Julid::from_str(invitation).map_err(|_| CreateUserErrorKind::BadInvitation)?;
let invited_by = validate_invitation(invitation, &mut tx).await?; let invited_by = validate_invitation(invitation, &mut tx).await?;
let user = sqlx::query_as(CREATE_QUERY) let user = sqlx::query_as(CREATE_QUERY)
@ -444,7 +443,7 @@ mod test {
.await .await
.unwrap(); .unwrap();
std::thread::sleep(Duration::from_millis(100)); std::thread::sleep(Duration::from_millis(500));
let username = "too slow"; let username = "too slow";

View file

@ -16,7 +16,7 @@ const LAST_SEEN_QUERY: &str = "update users set last_seen = (select unixepoch())
const INSERT_QUERY: &str = const INSERT_QUERY: &str =
"insert into users (id, username, displayname, email, pwhash, invited_by) values ($1, $2, $3, $4, $5, $6)"; "insert into users (id, username, displayname, email, pwhash, invited_by) values ($1, $2, $3, $4, $5, $6)";
#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct User { pub struct User {
pub id: Julid, pub id: Julid,
pub username: String, pub username: String,
@ -25,6 +25,7 @@ pub struct User {
pub last_seen: Option<i64>, pub last_seen: Option<i64>,
pub pwhash: String, pub pwhash: String,
pub invited_by: Julid, pub invited_by: Julid,
pub is_active: bool,
pub digest: String, pub digest: String,
} }
@ -39,12 +40,29 @@ impl sqlx::FromRow<'_, SqliteRow> for User {
email: row.try_get("email")?, email: row.try_get("email")?,
last_seen: row.try_get("last_seen")?, last_seen: row.try_get("last_seen")?,
invited_by: row.try_get("invited_by")?, invited_by: row.try_get("invited_by")?,
is_active: row.try_get("is_active")?,
pwhash, pwhash,
digest, digest,
}) })
} }
} }
impl Default for User {
fn default() -> Self {
Self {
is_active: true,
id: Default::default(),
username: Default::default(),
displayname: Default::default(),
email: Default::default(),
last_seen: Default::default(),
pwhash: Default::default(),
invited_by: Default::default(),
digest: Default::default(),
}
}
}
impl Debug for User { impl Debug for User {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("User") f.debug_struct("User")
@ -55,6 +73,7 @@ impl Debug for User {
.field("last_seen", &self.last_seen) .field("last_seen", &self.last_seen)
.field("digest", &self.digest) .field("digest", &self.digest)
.field("invited_by", &self.invited_by.as_string()) .field("invited_by", &self.invited_by.as_string())
.field("is_active", &self.is_active)
.finish() .finish()
} }
} }