Schema 23: manually paired read/write relays

This commit is contained in:
Mike Dilger 2023-02-09 14:05:10 +13:00
parent 35ef834525
commit 4895de218e
4 changed files with 120 additions and 42 deletions

View File

@ -111,7 +111,7 @@ macro_rules! apply_sql {
}
fn upgrade(db: &Connection, mut version: u16) -> Result<(), Error> {
let current_version = 22;
let current_version = 23;
if version > current_version {
panic!(
"Database version {} is newer than this binary which expects version {}.",
@ -143,6 +143,7 @@ fn upgrade(db: &Connection, mut version: u16) -> Result<(), Error> {
apply_sql!(db, version, 20, "schema20.sql");
apply_sql!(db, version, 21, "schema21.sql");
apply_sql!(db, version, 22, "schema22.sql");
apply_sql!(db, version, 23, "schema23.sql");
tracing::info!("Database is at version {}", version);
Ok(())
}

View File

@ -14,12 +14,13 @@ pub struct DbPersonRelay {
pub person: String,
pub relay: RelayUrl,
pub last_fetched: Option<u64>,
pub last_suggested_kind2: Option<u64>,
pub last_suggested_kind3: Option<u64>,
pub last_suggested_nip05: Option<u64>,
pub last_suggested_bytag: Option<u64>,
pub read: bool,
pub write: bool,
pub manually_paired_read: bool,
pub manually_paired_write: bool,
}
impl DbPersonRelay {
@ -31,15 +32,18 @@ impl DbPersonRelay {
let sql = format!(
"SELECT person, relay, person_relay.last_fetched, \
last_suggested_kind2, last_suggested_kind3, \
last_suggested_kind3, \
last_suggested_nip05, last_suggested_bytag, \
person_relay.read, person_relay.write \
person_relay.read, person_relay.write, \
person_relay.manually_paired_read, person_relay.manually_paired_write \
FROM person_relay \
INNER JOIN relay ON person_relay.relay=relay.url \
WHERE person IN ({}) ORDER BY person, \
person_relay.write DESC, relay.rank DESC, \
person_relay.write DESC, \
person_relay.manually_paired_write DESC, \
relay.rank DESC, \
last_suggested_kind3 DESC, \
last_suggested_nip05 DESC, last_suggested_kind2 DESC, \
last_suggested_nip05 DESC, \
last_fetched DESC, last_suggested_bytag DESC",
repeat_vars(pubkeys.len())
);
@ -61,12 +65,13 @@ impl DbPersonRelay {
person: row.get(0)?,
relay: url,
last_fetched: row.get(2)?,
last_suggested_kind2: row.get(3)?,
last_suggested_kind3: row.get(4)?,
last_suggested_nip05: row.get(5)?,
last_suggested_bytag: row.get(6)?,
read: row.get(7)?,
write: row.get(8)?,
last_suggested_kind3: row.get(3)?,
last_suggested_nip05: row.get(4)?,
last_suggested_bytag: row.get(5)?,
read: row.get(6)?,
write: row.get(7)?,
manually_paired_read: row.get(8)?,
manually_paired_write: row.get(9)?,
});
}
}
@ -80,9 +85,10 @@ impl DbPersonRelay {
pub async fn insert(person_relay: DbPersonRelay) -> Result<(), Error> {
let sql = "INSERT OR IGNORE INTO person_relay (person, relay, last_fetched, \
last_suggested_kind2, last_suggested_kind3, \
last_suggested_nip05, last_suggested_bytag, read, write) \
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
last_suggested_kind3, \
last_suggested_nip05, last_suggested_bytag, read, write, \
manually_paired_read, manually_paired_write) \
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
spawn_blocking(move || {
let maybe_db = GLOBALS.db.blocking_lock();
@ -93,12 +99,13 @@ impl DbPersonRelay {
&person_relay.person,
&person_relay.relay.0,
&person_relay.last_fetched,
&person_relay.last_suggested_kind2,
&person_relay.last_suggested_kind3,
&person_relay.last_suggested_nip05,
&person_relay.last_suggested_bytag,
&person_relay.read,
&person_relay.write,
&person_relay.manually_paired_read,
&person_relay.manually_paired_write,
))?;
Ok::<(), Error>(())
})
@ -283,14 +290,89 @@ impl DbPersonRelay {
Ok(())
}
#[allow(dead_code)]
pub async fn set_manual_pairing(
person: PublicKeyHex,
read_relays: Vec<RelayUrl>,
write_relays: Vec<RelayUrl>,
) -> Result<(), Error> {
// Clear the current ones
let sql1 = "UPDATE person_relay SET manually_paired_read=0, manually_paired_write=0 WHERE person=?";
// Set the reads
let mut sql2: String = "".to_owned();
let mut params2: Vec<String> = vec![person.to_string()];
if !read_relays.is_empty() {
sql2 = format!(
"UPDATE person_relay SET manually_paired_read=1 WHERE person=? AND relay IN ({})",
repeat_vars(read_relays.len())
);
for relay in read_relays.iter() {
params2.push(relay.to_string());
}
}
// Set the writes
let mut sql3: String = "".to_owned();
let mut params3: Vec<String> = vec![person.to_string()];
if !write_relays.is_empty() {
sql3 = format!(
"UPDATE person_relay SET manually_paired_write=1 WHERE person=? AND relay IN ({})",
repeat_vars(write_relays.len())
);
for relay in write_relays.iter() {
params3.push(relay.to_string());
}
}
spawn_blocking(move || {
let maybe_db = GLOBALS.db.blocking_lock();
let db = maybe_db.as_ref().unwrap();
let inner = || -> Result<(), Error> {
let mut stmt = db.prepare("BEGIN TRANSACTION")?;
stmt.execute(())?;
let mut stmt = db.prepare(sql1)?;
stmt.execute((person.as_str(),))?;
if !read_relays.is_empty() {
let mut stmt = db.prepare(&sql2)?;
stmt.execute(rusqlite::params_from_iter(params2))?;
}
if !write_relays.is_empty() {
let mut stmt = db.prepare(&sql3)?;
stmt.execute(rusqlite::params_from_iter(params3))?;
}
let mut stmt = db.prepare("COMMIT TRANSACTION")?;
stmt.execute(())?;
Ok(())
};
if let Err(e) = inner() {
tracing::error!("{}", e);
let mut stmt = db.prepare("ROLLBACK TRANSACTION")?;
stmt.execute(())?;
}
Ok::<(), Error>(())
})
.await??;
Ok(())
}
/// This returns the relays for a person, along with a score, in order of score
pub async fn get_best_relays(
pubkey: PublicKeyHex,
dir: Direction,
) -> Result<Vec<(RelayUrl, u64)>, Error> {
let sql = "SELECT person, relay, last_fetched, last_suggested_kind2, \
last_suggested_kind3, \
last_suggested_nip05, last_suggested_bytag, read, write \
let sql = "SELECT person, relay, last_fetched, last_suggested_kind3, \
last_suggested_nip05, last_suggested_bytag, read, write, \
manually_paired_read, manually_paired_write \
FROM person_relay WHERE person=?";
let ranked_relays: Result<Vec<(RelayUrl, u64)>, Error> = spawn_blocking(move || {
@ -309,12 +391,13 @@ impl DbPersonRelay {
person: row.get(0)?,
relay: url,
last_fetched: row.get(2)?,
last_suggested_kind2: row.get(3)?,
last_suggested_kind3: row.get(4)?,
last_suggested_nip05: row.get(5)?,
last_suggested_bytag: row.get(6)?,
read: row.get(7)?,
write: row.get(8)?,
last_suggested_kind3: row.get(3)?,
last_suggested_nip05: row.get(4)?,
last_suggested_bytag: row.get(5)?,
read: row.get(6)?,
write: row.get(7)?,
manually_paired_read: row.get(8)?,
manually_paired_write: row.get(9)?,
};
dbprs.push(dbpr);
}
@ -390,10 +473,10 @@ impl DbPersonRelay {
// This is the ranking we are using. There might be reasons
// for ranking differently.
// write (score=20) [ they claim (to us) ]
// manually_paired_write (score=20) [ we claim (to us) ]
// kind3 tag (score=5) [ we say ]
// nip05 (score=4) [ they claim, unsigned ]
// fetched (score=3) [ we found ]
// kind2 (score=2) [ they mention ]
// bytag (score=1) [ someone else mentions ]
let now = Unixtime::now().unwrap().0 as u64;
@ -409,7 +492,7 @@ impl DbPersonRelay {
let mut score = 0;
// 'write' is an author-signed explicit claim of where they write
if dbpr.write {
if dbpr.write || dbpr.manually_paired_write {
score += 20;
}
@ -428,11 +511,6 @@ impl DbPersonRelay {
score += scorefn(when, 60 * 60 * 24 * 3, 3);
}
// kind2 is an author-signed relay recommendation
if let Some(when) = dbpr.last_suggested_kind2 {
score += scorefn(when, 60 * 60 * 24 * 30, 2);
}
// last_suggested_bytag is an anybody-signed suggestion
if let Some(when) = dbpr.last_suggested_bytag {
score += scorefn(when, 60 * 60 * 24 * 2, 1);
@ -461,10 +539,10 @@ impl DbPersonRelay {
// This is the ranking we are using. There might be reasons
// for ranking differently.
// read (score=20) [ they claim (to us) ]
// manually_paired_read (score=20) [ we claim (to us) ]
// kind3 tag (score=5) [ we say ]
// nip05 (score=4) [ they claim, unsigned ]
// fetched (score=3) [ we found ]
// kind2 (score=2) [ they mention ]
// bytag (score=1) [ someone else mentions ]
let now = Unixtime::now().unwrap().0 as u64;
@ -480,7 +558,7 @@ impl DbPersonRelay {
let mut score = 0;
// 'read' is an author-signed explicit claim of where they read
if dbpr.read {
if dbpr.read || dbpr.manually_paired_read {
score += 20;
}
@ -499,11 +577,6 @@ impl DbPersonRelay {
score += scorefn(when, 60 * 60 * 24 * 3, 3);
}
// kind2 is an author-signed relay recommendation
if let Some(when) = dbpr.last_suggested_kind2 {
score += scorefn(when, 60 * 60 * 24 * 30, 2);
}
// last_suggested_bytag is an anybody-signed suggestion
if let Some(when) = dbpr.last_suggested_bytag {
score += scorefn(when, 60 * 60 * 24 * 2, 1);

3
src/db/schema23.sql Normal file
View File

@ -0,0 +1,3 @@
ALTER TABLE person_relay DROP COLUMN last_suggested_kind2;
ALTER TABLE person_relay ADD COLUMN manually_paired_read INTEGER NOT NULL DEFAULT 0;
ALTER TABLE person_relay ADD COLUMN manually_paired_write INTEGER NOT NULL DEFAULT 0;

View File

@ -660,12 +660,13 @@ impl Overlord {
person: pkhex.to_string(),
relay,
last_fetched: None,
last_suggested_kind2: None,
last_suggested_kind3: Some(now), // consider it our claim in our contact list
last_suggested_nip05: None,
last_suggested_bytag: None,
read: true,
write: true,
read: false,
write: false,
manually_paired_read: true,
manually_paired_write: true,
})
.await?;