Browse Source

first attempt to deal with resurrected files properly

David Mazieres 6 years ago
parent
commit
6026628d94
4 changed files with 46 additions and 18 deletions
  1. 1
    1
      muchsync.h
  2. 42
    16
      protocol.cc
  3. 1
    1
      sql_db.cc
  4. 2
    0
      sql_db.h

+ 1
- 1
muchsync.h View File

@@ -15,7 +15,7 @@ using std::string;
15 15
 void muchsync_server(sqlite3 *db, notmuch_db &nm);
16 16
 void muchsync_client(sqlite3 *db, notmuch_db &nm,
17 17
 		     std::istream &in, std::ostream &out);
18
-std::istream &get_response(std::istream &in, string &line);
18
+std::istream &get_response(std::istream &in, string &line, bool err_ok = true);
19 19
 
20 20
 /* muchsync.cc */
21 21
 extern bool opt_fullscan;

+ 42
- 16
protocol.cc View File

@@ -316,8 +316,6 @@ msg_sync::hash_sync(const versvector &rvv,
316 316
 {
317 317
   hash_info lhi;
318 318
   i64 docid = -1;
319
-  bool docid_valid = false;
320
-  bool new_msgid = false;
321 319
 
322 320
   if (hashdb.lookup(rhi.hash)) {
323 321
     /* We might already be up to date from a previous sync that never
@@ -394,18 +392,30 @@ msg_sync::hash_sync(const versvector &rvv,
394 392
 	notmuch_db::get_docid(nm_.add_message(target,
395 393
 					      tip ? &tip->tags : nullptr,
396 394
 					      &isnew));
397
-      docid_valid = true;
398 395
       i64 dir_id = get_dir_docid(li.first);
399 396
       add_file_.reset().param(dir_id, newname, docid, ts_to_double(sb.st_mtim),
400 397
 			      i64(sb.st_ino), hashdb.hash_id()).step();
401 398
       if (isnew) {
402
-	new_msgid = true;
403
-	// XXX tip might be NULL here when undeleting a file
404
-	update_message_id_stamp_.reset()
405
-	  .param(tip->tag_stamp.first, tip->tag_stamp.second, docid).step();
406
-	add_tag_.reset().bind_int(1, docid);
407
-	for (auto t : (tip ? tip->tags : nm_.new_tags))
408
-	  add_tag_.reset().bind_text(2, t).step();
399
+	// tip might be NULL here when undeleting a file
400
+	if (tip) {
401
+	  update_message_id_stamp_.reset()
402
+	    .param(tip->tag_stamp.first, tip->tag_stamp.second, docid).step();
403
+	  add_tag_.reset().bind_int(1, docid);
404
+	  for (auto t : tip->tags)
405
+	    add_tag_.reset().bind_text(2, t).step();
406
+	}
407
+	else {
408
+	  record_docid_.param(rhi.message_id, docid).step().reset();
409
+	  // The empty tag is always invalid, so if worse comes to
410
+	  // worst and we crash at the wrong time, the next scan will
411
+	  // end up bumping the version number on this message ID.
412
+	  add_tag_.reset().param(docid, "");
413
+#if 0
414
+	  add_tag_.reset().bind_int(1, docid);
415
+	  for (auto t : nm_.new_tags)
416
+	    add_tag_.reset().bind_text(2, t).step();
417
+#endif
418
+	}
409 419
       }
410 420
     }
411 421
   /* remove extra links */
@@ -444,9 +454,6 @@ msg_sync::hash_sync(const versvector &rvv,
444 454
       }
445 455
     }
446 456
 
447
-  if (new_msgid && docid_valid)
448
-    record_docid_.param(rhi.message_id, docid).step().reset();
449
-
450 457
   /* Adjust link counts in database */
451 458
   for (auto li : save_needlinks)
452 459
     if (li.second != 0) {
@@ -713,7 +720,7 @@ muchsync_server(sqlite3 *db, notmuch_db &nm)
713 720
 	  cout << "510 unknown hash\n";
714 721
 	break;
715 722
       case 't':			// tinfo command
716
-	if (tagdb.lookup(key))
723
+	if (tagdb.lookup(percent_decode(key)))
717 724
 	  cout << "210 " << tagdb.info() << '\n';
718 725
 	else
719 726
 	  cout << "510 unkown message id\n";
@@ -836,7 +843,7 @@ muchsync_server(sqlite3 *db, notmuch_db &nm)
836 843
 }
837 844
 
838 845
 istream &
839
-get_response (istream &in, string &line)
846
+get_response (istream &in, string &line, bool err_ok)
840 847
 {
841 848
   if (!getline (in, line))
842 849
     throw runtime_error ("premature EOF");
@@ -846,7 +853,7 @@ get_response (istream &in, string &line)
846 853
     throw runtime_error ("unexpected empty line");
847 854
   if (line.size() < 4)
848 855
     throw runtime_error ("unexpected short line");
849
-  if (line.front() != '2')
856
+  if (line.front() != '2' && (line.front() != '5' || !err_ok))
850 857
     throw runtime_error ("bad response: " + line);
851 858
   return in;
852 859
 }
@@ -916,6 +923,13 @@ muchsync_client (sqlite3 *db, notmuch_db &nm,
916 923
     maybe_commit();
917 924
   }
918 925
   out << "tsync\n";
926
+  int extra_tags = 0;
927
+  for (sqlstmt_t nolinks (db, "SELECT message_id FROM message_ids"
928
+			  " WHERE replica = 0 AND version = 0;");
929
+       nolinks.step().row();) {
930
+    extra_tags++;
931
+    out << "tinfo " << permissive_percent_encode(nolinks.str(0)) << '\n';
932
+  }
919 933
   print_time ("received hashes of new files");
920 934
   down_body = pending;
921 935
 
@@ -950,6 +964,18 @@ muchsync_client (sqlite3 *db, notmuch_db &nm,
950 964
     msync.tag_sync(remotevv, ti);
951 965
     maybe_commit();
952 966
   }
967
+  for (; extra_tags > 0; extra_tags--) {
968
+    get_response(in, line, true);
969
+    if (line[0] == '5')
970
+      continue;
971
+    is.str(line.substr(4));
972
+    if (!(is >> ti))
973
+      throw runtime_error ("could not parse tag_info: " + line.substr(4));
974
+    if (opt_verbose > 2)
975
+      cerr << ti << '\n';
976
+    msync.tag_sync(remotevv, ti);
977
+    maybe_commit();
978
+  }
953 979
   print_time ("received tags of new and modified messages");
954 980
 
955 981
   record_peer_vector(db);

+ 1
- 1
sql_db.cc View File

@@ -191,7 +191,7 @@ show_sync_vector (const versvector &vv)
191 191
   return sb.str();
192 192
 }
193 193
 
194
-static string
194
+string
195 195
 permissive_percent_encode (const string &raw)
196 196
 {
197 197
   ostringstream outbuf;

+ 2
- 0
sql_db.h View File

@@ -137,4 +137,6 @@ std::istream &operator>> (std::istream &is, tag_info &ti);
137 137
 
138 138
 string trashname (const string &maildir, const string &hash);
139 139
 
140
+string permissive_percent_encode (const string &raw);
141
+
140 142
 #endif /* !_SQL_DB_H */

Loading…
Cancel
Save