def on_summary(self, rtype, hid, summary): # Check for existing records self.dbc.execute( "SELECT score, data FROM _records " "WHERE rtype = ? AND hid = ?", (rtype, buffer(hid))) row = self.dbc.fetchone() # If no existing entry, return true if row == None: return True # Score incoming and new record score = record.score_record(rtype, hid, summary) # If it's negative, drop if score < 0: return False (cscore, data) = row # If new record isn't better, forget it if cscore >= score: return False # If it's a WT record, just update the summary if rtype == record.RT_WORKTOKEN: self.dbc.execute( "REPLACE INTO _records " + "(rtype, hid, score, data, score) " + "VALUES (?, ?, ?, ?, ?)", (rtype, buffer(hid), buffer(summary), buffer(data), score)) return False # Otherwise I need the whole data return True
def on_record(self, rtype, hid, summary, data): # Validate + Score if not record.validate_record(rtype, self.tid, self.verify, hid, summary, data): logger.warn("Invalid record, type = %d", rtype) return False score = record.score_record(rtype, hid, summary) # Delete any existing version with lower score self.dbc.execute( "DELETE FROM _records " + "WHERE rtype = ? AND hid = ? AND score < ?", (rtype, buffer(hid), score)) if self.dbc.rowcount > 0: self.db_size -= 100 + len(data) if rtype == record.RT_SIGNED and hid == SCHEMA_HID and self.schema is not None: self.schema.uninstall(self.dbc) # Insert new row if not already there self.dbc.execute( "INSERT OR IGNORE INTO _records " + "(rtype, hid, summary, data, score) " + "VALUES (?, ?, ?, ?, ?)", (rtype, buffer(hid), buffer(summary), buffer(data), score)) if self.dbc.rowcount > 0: self.db_size += 100 + len(data) if rtype == record.RT_SIGNED and hid == SCHEMA_HID: self.__new_schema() if rtype == record.RT_WORKTOKEN and self.schema is not None: self.schema.insert_record(self.dbc, hid, summary, data, score) # Shrink as needed self.__shrink() # Maybe found a pubkey if rtype == record.RT_PUBKEY: logger.info("Setting public key") self.__set_pubkey(data) return True
def test_ordered(self): # Make a SyncStore that holds 20 objects tid = ''.join(chr(random.randint(0, 255)) for _ in range(20)) dbc = dbconn.DbConn(":memory:") store = SyncStore(tid, dbc, 21 * (len('text/plain') + RECORD_OVERHEAD)) recs = [] # Make 30 random entries and insert them for i in range(30): (hid, summary, data) = record.make_worktoken_record('text/plain', str(i)) score = record.score_record(record.RT_WORKTOKEN, hid, summary) recs.append((score, hid, str(i))) store.on_record(record.RT_WORKTOKEN, hid, summary, data) # Sort entries by score recs.sort(key=lambda x: x[0]) # Check the the right elements are there for i in range(10): self.assertTrue(store.get_data(record.RT_WORKTOKEN, recs[i][1])[1] == None) for i in range(10, 30): self.assertTrue(store.get_data(record.RT_WORKTOKEN, recs[i][1])[1] == recs[i][2])